打印链接列表中的值对

时间:2016-09-30 10:55:49

标签: c algorithm linked-list

这是我创建链表的代码:

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>

typedef struct list_element {
    int inf;
    struct list_element *next;
} List;

List *create() {
    List *p, *punt;
    int x = 1;/*Random number but different from 0*/
    p = (List *)malloc(sizeof(List));
    printf("\nFirst value: ");
    scanf("%d", &p->inf);
    punt = p;

    while (1) {/*Till x different from 0*/
        printf("\nNext value: ");
        scanf("%d", &x);
        if (x == 0)
            break;
        punt->next = (List *)malloc(sizeof(List));
        punt = punt->next;
        punt->inf = x;
    }
    punt->next = NULL;
    return p;
}

int main(void) {
    List *a;
    a = create();
}

假设要在输入(scanf)中发送以下值:

  

10 20 30 40 50 15 35

我需要创建一个void函数,它向stdout发送总和为50的数字对的列表,所以在这种情况下输出将是

  

10 40

     

20 30

     

15 35

为此,我使用了两种不同的功能:
在第一个中,我在int数组和第二个函数中复制了链表的值,使用了回溯算法(在刚刚创建的数组上执行),我找到了解决方案。
这是我的解决方案:

void BackTrack(int n, int s, int x[7], int z[7], int partial, int max, int check) {
    if (n == s) {
        int y = 0;
        for (int i = 0; i < n; i++){
            if (z[i] != 0 && check == 2 && partial == max) {
                printf("%d ", z[i]);
                y++;
            }
        }
        if(y != 0)
            printf("\n");
        return;
    }

    z[s] = 0;
    BackTrack(n, s + 1, x, z, partial, max, check);

    if (x[s] + partial <= max) {
        z[s] = x[s];
        partial += x[s];
        check++;
        BackTrack(n, s + 1, x, z, partial, max, check);
    }
}

void ARRAY(List *p) {
    int *x = NULL;
    int i;
    for (i = 0; p != NULL; i++){
        x = realloc(x, sizeof(int) * (i + 1));
        x[i] = p->inf;
        p = p->next;
    }
    int *z = malloc(sizeof(int) * i);
    BackTrack(i, 0, x, z, 0, 50, 0);
}

但我想知道是否有办法在没有使用阵列对话之前使用这样做?所以直接在链表上点击夫妻。感谢

3 个答案:

答案 0 :(得分:2)

void FindPairs(List *list, int sum) {

  struct list_element *i, *j;

  for (i = list; i; i = i->next) {
    if (i->inf > sum)
      continue;
    for (j = i->next; j; j = j->next) {
      if (i->inf + j->inf == sum)
        printf("%d %d\n", i->inf, j->inf);
    }
  }
}

答案 1 :(得分:0)

  1. 简单的方法是在列表上使用2 for循环并检查所需的总和,Complexity - O(n ^ 2)。

  2. 使用hashmap,将第一个值存储在哈希映射中,现在从第二个值存储,如果sum-2ndValue存在于hashmap中,则解决方案,否则插入hashmap。 - 时间复杂度 - O(n),空间复杂度 - O(n)。

答案 2 :(得分:-1)

我有空格,将所有值复制到排序数据结构中,如排序列表。比你可以从两边迭代并以这种方式找到对。

速度:

  • 创建排序列表: O(n log n)
  • 迭代找到对: O(n)

如果空间不足,则需要经常遍历链表。

<强>伪代码:

nodeLeft=fistNodeInList
while(nodeLeft.hasNext)
  nodeRight=nodeLeft
  while(nodeRight.hasNext)
    nodeRight= nodeRight.next
    if(nodeRight.value+nodeLeft.value= sum
      print odeRight.value nodeLeft.value
  nodeLeft=nodeLeft.next

O(n²)速度