fix for a reversed link

时光总嘲笑我的痴心妄想 提交于 2020-04-16 05:49:31

问题


hey for some reason my linked list is printing in the reversed ordear for example if my input is 2->4->6 my output is 6->4->2

list* add_int_list(list* a,int b)
{
    list *temp;
    temp = (list*)malloc(sizeof(list*));
    temp->next = NULL;
    if (a->next == NULL)//insert to the first node
    {
        temp->data = b;
        temp->next = a;
        a = temp;

    }
    else 
    {
        temp->data = b;
        temp->next = a;
        a = temp;//I think the problem is here, couldnt find how to fix 
}

回答1:


For starters in this statement

temp = (list*)malloc(sizeof(list*));
                            ^^^^^

there is allocated memory of the size equal to the size of pointer instead of the size of the node. You have to write either

temp = (list*)malloc(sizeof(list));

or

temp = (list*)malloc(sizeof( *temp));

This if statement

if (a->next == NULL)

can invoke undefined behavior because initially the list can be empty. So the pointer a can be equal to NULL. That is there is used a null pointer to access memory.

There is no difference between these two code blocks after the if and else parts of the if-else statement

if (a->next == NULL)//insert to the first node
{
    temp->data = b;
    temp->next = a;
    a = temp;
}
else 
{
    temp->data = b;
    temp->next = a;
    a = temp;//
}

That is the both code snippet try insert a new-node in the beginning of the list.

It is a general approach to insert a new node in a singly-linked one-sided list in its beginning. To append a node to such a list to its end is inefficient because the whole list must be traversed.

If you want to append a node to the end of a singly linked list then make it two-sided.

Here is a demonstrative program.

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

typedef struct Node
{
    int data;
    struct Node *next;
} Node;

typedef struct List
{
    Node *head;
    Node *tail;
} List;

int push_front( List *list, int data )
{
    Node *new_node = malloc( sizeof( Node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->data = data;
        new_node->next = list->head;

        list->head = new_node;

        if ( list->tail == NULL ) list->tail = list->head;
    }

    return success;
}

int push_back( List *list, int data )
{
    Node *new_node = malloc( sizeof( Node ) );
    int success = new_node != NULL;

    if ( success )
    {
        new_node->data = data;
        new_node->next = NULL;

        if ( list->tail == NULL )
        {
            list->head = list->tail = new_node;
        }
        else
        {
            list->tail = list->tail->next = new_node;
        }
    }   

    return success;
}

void output( const List *list )
{
    for ( const Node *current = list->head; current != NULL; current = current->next )
    {
        printf( "%d -> ", current->data );
    }

    puts( "null" );
}

int main(void) 
{
    List list = { .head = NULL, .tail = NULL };

    const int N = 10;

    for ( int i = 0; i < N; i++ )
    {
        if ( i % 2 != 0 )
        {
            push_front( &list, i );
        }
        else
        {
            push_back( &list, i );
        }

        output( &list );
    }

    return 0;
}

Its output is

0 -> null
1 -> 0 -> null
1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> null
3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> null
5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> null
7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null
9 -> 7 -> 5 -> 3 -> 1 -> 0 -> 2 -> 4 -> 6 -> 8 -> null

In this demonstrative program even numbers are inserted in the end of the list using the function push_back and odd numbers are inserted in the beginning of the list using the function push_front.

If you C compiler does not support designated initializers then this declaration

List list = { .head = NULL, .tail = NULL };

can be changed the following way

List list = { NULL, NULL };



回答2:


The problem is that your code is appending the node to the front of the list in both cases. If you want to always append to the end of the list, you need to walk the list until the end and then add temp there.

I wrote this code off-the-cuff, so take it as pseudo-code:

// Assuming this function returns the front (head) of the list.
list* append_element_to_list(list* a, int b)
{
    list *newNode;
    newNode = (list*)malloc(sizeof(list*));
    newNode->data = b;

    // Handle the case where `a` is NULL. This means
    // no list was passed in, so the newly created node
    // will be returned to start the list.
    if (a == NULL)
    {
      return newNode;
    }

    // If we get this far, it means `a` contains at least
    // one node. So walk the list until the end.
    list *currentNode = a;
    while (currentNode->next != NULL)
    {
      currentNode = currentNode->next;
    }

    // Once you reach the end of the list, set
    // `newNode` as the last node.
    currentNode->next = newNode;

    // The front of the list hasn't changed, so return that.
    return a;
}



回答3:


You have some mistakes in your code, I am making correction in your code, just changing what required. first I want to focus on main issue, before inserting at last of any list, you should iterate the complete list.

  i = a; // to iterate
  while(i->next != NULL)
  {
   i = i->next;
  }
  // Now i is last node of list a
  i->next = temp;

Now the below code, I just check it on TurboC, I am using your function and inserting three values and then printing the list. Please see all the line comments:

#include <stdio.h>
#include <malloc.h>
typedef struct node{
 int data;
 struct node *next;

}list;

list* add_int_list(list* a,int b)
{
    list *temp;
    list *i;

    temp = (list*)malloc(sizeof(list*));
    temp->next = NULL;
    temp->data = b;

    if (a == NULL)//insert to the first node
    {
       //temp->data = b; -  done above
    //temp->next = a; no reason for this line
        a = temp;
    }
    else
    {
       // temp->data = b; - done above
       //temp->next = a; wrong logic
       // a = temp;//I think the problem is here, couldnt find how to fix : Yes it is also wrong

      //Here it required to iterate complete list and go to end

      i = a; // to iterate
      while(i->next != NULL)
      {
       i = i->next;
      }
      // Now i is last node of list a
      i->next = temp;
    }

    return a;
}
void printList(list *root)
{
   list *i;

   if(root == NULL)
   {
    printf("List is empty");
   }
   else
   {
    i = root;
    while(i != NULL){
      printf("%d,",i->data);
      i = i->next;
    }
   }
}
int main()
{
  list *root = NULL;
  clrscr();
  root =  add_int_list(root, 3);
  root =  add_int_list(root, 4);
  root =  add_int_list(root, 5);
  printList(root);
    return 0;
}


来源:https://stackoverflow.com/questions/61116597/fix-for-a-reversed-link

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!