如何有效地添加2个不同大小的链表

时间:2014-02-15 16:35:44

标签: c linked-list singly-linked-list

我的功能有两个不同大小的链接列表。他们已经逆转了。其他一切似乎都有效,但我知道问题出现在while循环中

 while(num1 != NULL && num2 != NULL)

当我使用&&运算符它只停留到第一个完成列表的末尾(我理解)。但是,当我尝试使用或(||)运算符时,我的整个程序就崩溃了。 有人可以帮我弄清楚出了什么问题。

这是功能。和我的主要。

//adds the two linked lists for their sum
node *addLargeNumber(node *num1, node *num2) {
    node *result = NULL;
    node *prev = NULL;
    node *temp;
    int sum, carry = 0;

    while(num1 != NULL || num2 != NULL) { //while both lists exists or either is not empty
        /*calculate values for the result. the next digit with be the sum of the carry
        from previous number(if any) digit from 1st list and digit from second list*/

        sum = carry + (num1->data) + (num2->data);                   
        if (sum > 9) carry = 1;
            else carry = 0;
        sum = sum % 10; //just want ones column from sum to put in result      
        temp = createNode(sum);

        if(result == NULL) 
            result = temp; //if it is first node, make it the head  
        else 
            prev->next = temp; //if not first node, connect it to rest
        prev = temp; //reset prev or next insertion

        // move to next nodes in both lists
        if(num1 != NULL) num1 = num1->next;
        if(num2 != NULL) num2 = num2->next;
    }

      if(carry > 0) temp->next = createNode(carry);        
      return result;
}

主要功能

int main(void) {
    node *storeNumber();
    void reverseList();
    void printList();
    node *addLargeNumber();
    node *add();

    char number1[numsize], number2[numsize], bigSum[numsize];
    node *top;
    char command;
    int number;

    FILE *in = fopen("input.txt", "r");
    FILE *out = fopen("output.txt", "w");

    while(fscanf(in, "%c", &command) != EOF) {   //while there are no more commands to be read
        top = NULL;  
        //adding two large numbers with linked list
        if(command == 'A') {
            fscanf(in, "%s", &number1);
            fscanf(in, "%s", &number2);   
            node *top1 = storeNumber(number1);
            node *top2 = storeNumber(number2);
            node *sum = addLargeNumber(top1, top2);

            printList(top1);
            printf("  +  ");
            printList(top2);
            printf("  =  ");
            printList(sum);
            printf("\n\n");
            fscanf(in, "%c", &command); 
        }
    }
    system("Pause");
    return 0;   
}

3 个答案:

答案 0 :(得分:0)

编辑:

在尝试更好地了解您要做的事情之后,我认为您需要添加一个进位> 0在while循环中带有OR子句。我还认为你需要在添加之前将每个数据元素完全分别添加到数字的和检查中。通过执行这两项操作,您应该继续添加超过初始数据的节点,如果确实需要将进位推送到您的总和之后(或向左)。

我认为以下内容应该有效,您可以在循环后取出例程的最后两行检查进位。作为为什么它失败的答案,在执行添加时,它是NON-CHECKING为NULL。如果您有一个比另一个更长的数字,则在添加之前不会执行NULL检查,这会导致崩溃。

// while both lists exists or either is not empty
while(num1 != NULL || num2 != NULL || carry > 0){

    /*calculate values for the result. the next digit with be the sum of the carry
    from previous number(if any) digit from 1st list and digit from second list*/

    // Add in each element separately do detect for NULL on the fly
    sum = carry;
    if(num1->data != NULL) sum += num1-data;        
    if(num2->data != NULL) sum += num2-data;

    // Test to see if we should carry
    if (sum > 9) carry = 1;
        else carry = 0;

    // Lets keep the remainder as the value for this particular digit of the sum
    sum = sum % 10; //just want ones column from sum to put in result
    temp = createNode(sum);

    if(result == NULL) 
        result = temp; //if it is first node, make it the head  
    else 
        prev->next = temp; //if not first node, connect it to rest
    prev = temp; //reset prev or next insertion

    // move to next nodes in both lists
    if(num1 != NULL) num1 = num1->next;
    if(num2 != NULL) num2 = num2->next;
}

试试这个:

// Changed this from || to && so that either of them will force a 
// stop in the looping
while(num1 != NULL && num2 != NULL) {

    ......

    // move to next nodes in both lists - Changed these two lines to force the null
    // to pop out within the while loop checking
    num1 = num1->next;
    num2 = num2->next;
}

您需要更改||或者和&&&因为while循环将继续,而它们的EITHER为null。此外,您需要强制移动到下一个值而不检查最后的NULL。如果没有MOVING进入null,while循环将永远不会达到空点,因此您将创建一个无限循环。

还应该注意的是,你不需要if语句来保护主加法器循环中最底部的两行,因为如果正确完成,你的循环检查就会解决这个问题。

答案 1 :(得分:0)

如果您使用||“或”运算符,其中一个num可能为null,并且当您尝试访问num1->datanum2->data

时程序崩溃

尝试类似:

 sum = carry;
 if(num1 != NULL) sum += num1->data;
 if(num2 != NULL) sum += num2->data;

 if(num1!= NULL) num1 = num1->next;
 if(num2!= NULL) num2 = num2->next;

答案 2 :(得分:0)

该程序没有问题。确保“可能存在无限节点”,以便它可能无法到达终点。如果一切正确,可能会由于操作员的短路特性而出现问题。节点增量也可能存在一些问题,请检查一下。在这种情况下,请尝试NESTED WHILE语句。         而(NUM1!= NULL)         {         而(NUM2!= NULL)         {         / * ...............         ..................         ............... * /         }         }