打印将从链接列表中删除该值

时间:2009-05-06 16:54:54

标签: c linked-list traversal

作为作业的一部分,我需要写两个函数:

  1. 一个函数,它汇总了两个表示为链表的自然数
  2. 打印以相同方式表示的数字的函数。
  3. 由于某种原因,两个函数分别完美地工作,但是当我尝试在sum函数的结果上使用print函数时,它会在print函数的开头改变sum的值,并打印出错误的价值。当我使用printf在main中打印相同的值时,没有问题。我的代码详述如下。有任何想法吗?

    void main() 
    {
      int a[1] = { 1 },
        b[1] = { 2 };
      int * *pa, **pb;
      List lst1, lst2;
      List sum;
    
      pa = (int * *) malloc(sizeof(int * )); * pa = &a[0];
      pb = (int * *) malloc(sizeof(int * )); * pb = &b[0];
      lst1 = arrToList(pa, 1);
      lst2 = arrToList(pb, 1);
      addNumbers(lst1, lst2, &sum);
      //printf("%d\n",*(sum.head->dataPtr));
      printNumber(sum);
    }
    
    //a function that recieves a number represented ad a list and prints it
    void printNumber(List num) 
    {
      ListNode * curr;
      int currData,
      i,
      number;
    
      if (isEmptyList(num) == TRUE) 
        printf("the input was an empty list, nothing to print");
      else 
      {
        i = 0;
        number = 0;
        curr = num.head;
        while (curr != NULL) 
        {
          currData = *(curr - >dataPtr);
          number = number + currData * ((int) pow(10, i));
          curr = curr - >next;
          i++;
        }
        printf("%d \n", number);
      }
    }
    
    // a function that sums in list 
    // representation two numbers,
    // each represented as a list 
    void addNumbers(List n1, List n2, List * sum) 
    {
      ListNode * currN1;
      ListNode * currN2;
      ListNode * currSum;
      int currN1N2Sum; //stores the sum of the current digits in n1 and n2 
      int carrier,
      prevCarrier; //current and previous  carriers that carries +1 to the 
      next digit of sum
      if the lst sum was bigger then 9
    
      if ((isEmptyList(n1) == TRUE) || (isEmptyList(n2) == TRUE)) 
        printf("bad input =(");
      else 
      {
        currN1 = n1.head;
        currN2 = n2.head; * sum = createEmptyList();
        carrier = 0;
        prevCarrier = 0;
        while ((currN1 != NULL) && (currN2 != NULL)) 
        {
          currN1N2Sum = *(currN1->dataPtr) + *(currN2->dataPtr) + prevCarrier;
          if (currN1N2Sum > 9) 
          {
            carrier = 1;
            currN1N2Sum = currN1N2Sum - 10;
          }
          currSum = creatNewListNode( & currN1N2Sum, NULL);
          insertNodeToEnd(sum, currSum);
          prevCarrier = carrier;
          carrier = 0;
          currN1 = currN1 - >next;
          currN2 = currN2 - >next;
        } //while ((currL1!=NULL)&&(currL2!=NULL))
    
        while (currN1 != NULL) 
        {
          currN1N2Sum = *(currN1 - >dataPtr) + prevCarrier;
          currN1 = currN1 - >next;
          if (prevCarrier != 0) prevCarrier = 0;
        }
    
        while (currN2 != NULL) 
        {
          currN1N2Sum = *(currN2 - >dataPtr) + prevCarrier;
          currN2 = currN2 - >next;
          if (prevCarrier != 0) prevCarrier = 0;
        }
      } // ! ((isEmptyList(n1)==TRUE)||(isEmptyList(n2)==TRUE))
    }
    

    这是代码的其余部分:

    typedef struct listNode{
    int* dataPtr;
    struct listNode* next;
    } ListNode;
    
    typedef struct list
    {
    ListNode* head;
    ListNode* tail;
    } List;
    
    List createEmptyList()//creates and returns an empty linked list 
    {
        List res;
    
        res.head = res.tail = NULL;
    
        return res;
    }
    
    Bool isEmptyList ( List lst )//checks if a given list is empty or not
    {
        if (lst.head == NULL && lst.tail == NULL)
            return TRUE;
        else
            return FALSE;
    }
    
    void insertDataToEnd ( List * lst, int *dataPtr ) //inserts new data to the end of an existing linked list
    {
        ListNode * newTail;
        newTail = creatNewListNode ( dataPtr, NULL );
        insertNodeToEnd(lst,newTail);
    }
    
    void insertNodeToEnd ( List * lst, ListNode * newTail )//insert an existing node to an existing linked list
    {
        if (isEmptyList(*lst) == TRUE )
            insertNodeToStart ( lst,newTail );
        else
        {
            (*lst).tail -> next = newTail;
            newTail->next = NULL;
            (*lst).tail = newTail;
        }
    }
    
    
    ListNode * creatNewListNode ( int * dataPtr, ListNode * next )//inserts new node in an existing linked list
    {
        ListNode * res;
    
        res = (ListNode *) malloc (sizeof(ListNode));
    
        res -> dataPtr  = dataPtr;
        res -> next     = next;
    
        return res;
    }
    
    void insertNodeToStart  ( List * lst, ListNode * newHead )//inserts node to the begining of a given linked list
    {
        if ( isEmptyList( *lst ) == TRUE )
        {
            (*lst).head = newHead;
            (*lst).tail = newHead;
            newHead -> next = NULL;
        }
        else
        {
            newHead -> next = (*lst).head;
            (*lst).head = newHead; 
        }
    }
    

5 个答案:

答案 0 :(得分:5)

错误在addNumbers函数中。 当您添加节点以存储总和时,您将指针传递给变量currN1N2Sum,该变量是一个局部变量(存储在堆栈中)。当addNumbers函数终止时,局部变量的存储被释放。在该位置找到的值将保持不变,因此只要存储不被重用,它就显然是有效的。

这就是为什么你对addNumbers函数的印象是正确的。当调用printNumber函数时,存储被覆盖,你在那里找到一个不同的值。

这解释了你的错误。

addNumbers还有另一个问题。当您尝试添加两位数字时,currN1N2Sum的内容将被新值覆盖。

你应该做的是分配一个缓冲区(malloc)并将包含在currN1N2Sum中的值存储到其中。将指向缓冲区的指针传递给新节点。

顺便说一句:你可以在lst-> head中改变(* lst).head。它将使您的代码更具可读性。

答案 1 :(得分:0)

我们需要看一些代码:如何定义用于保存节点的数据结构,如何添加节点等。

以下行是可疑的:

    number=number+currData*((int)pow(10,i));

说,你有123个存储为1,2和3个节点:

    number =  0;
    number =  0 + 1 * 1   = 1;
    number =  1 + 2 * 10  = 21;
    number = 21 + 3 * 100 = 321;

但如果您存储的是3个,2个和1个节点,则可以获得:

    number =  0;
    number =  0 + 3 * 1   = 3;
    number =  3 + 2 * 10  = 23;
    number = 23 + 1 * 100 = 123;

这是你的问题吗?

答案 2 :(得分:0)

如果没有看到createNewListNode()的实施,我不是,如果这是一个问题,但这里需要考虑的事项:
dataPtr电话回来后,sum列表中的addNumbers()指向何处?

答案 3 :(得分:0)

我认为你可能会在指针方面搞乱事情......你在addNumbers中分配列表'sum'的方式似乎非常非常奇怪。 (如果它破坏了我就不会感到惊讶......)

尝试进行这些更改:

主要:

List *sum;
<...>
addNumbers(lst1,lst2,sum); //Note the absence of the reference operator &
printNumbers(*sum);

(或者,将printNumbers更改为接受(List *)而不是(List))。

希望这有助于XD


修改:

的 尝试在调用addNumbers()之前分配'sum'。

lst1 = arrToList(pa, 1);
lst2 = arrToList(pb, 1);
sum = createEmptyList();

我仍然认为你的数据结构有点奇怪:S

答案 4 :(得分:0)

你遇到了createEmptyList的问题。你在那里声明一个名为res的列表并返回结构,但是这个函数返回该结构的时间不再有效。 尝试使用malloc(用于struct),然后将指针返回给调用者。您可以在* sum。

的开头使用此功能

这是与chmike发现的类似的错误,所以你最好解决这两个问题。