节点插入,链接列表

时间:2016-08-31 13:47:03

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

我有这个代码,它通过它在开始时插入节点。这个代码还包含一个打印链表的函数,如果为空则打印链表是空的

当我运行此代码时,我的输出为链接列表为空

struct node {
    int data;
    node* next;
}* start = NULL;

void append(node* linkedlist, int data)
{
    node* new_element = NULL;
    new_element = (node*)malloc(sizeof(struct node));
    new_element->data = data;
    if (linkedlist == NULL) {
        linkedlist = new_element;
        new_element->next = NULL;
    }

    else {
        new_element->next = (linkedlist)->next;
        (linkedlist)->next = new_element;
    }
}

int main()
{
    append(start, 4);
    append(start, 5);
    printList(start);
}

更新

void printList(node* linkedlist)
{
    node* ptr = linkedlist;
    if (linkedlist == NULL) {
        printf("Linked list is empty");
        exit(0);
    }
    else {

        while (ptr != NULL) {
            cout << ptr->data;
            ptr = ptr->next;
        }
    }
}

我可能做错了什么?我应该改变什么才能使其发挥作用?

6 个答案:

答案 0 :(得分:3)

您的问题在这里linkedlist = new_element;将参数传递给函数时,它们按值传递。即使你传递pointer,你实际上也传递了该指针的副本(你可以通过在函数内部和函数外部打印linkedlist的地址来验证)。声明linkedlist = new_element;new_element分配给副本。一旦函数返回,你最终什么都没有(和内存泄漏)。请记住,当您需要更改指针本身时,必须使用双pointer **

答案 1 :(得分:2)

您输入的值start指向null。然后将其复制到另一个指针linkedlist并将其设置为新值。函数start仍指向null后,因为您从未更改start的值。

您可以尝试将声明更改为

void append(node *&linkedlist,int data)

如果您使用的是c ++编译器。

其他

void append(node **linkedlist,int data)
...
append(&start,4);

如果您使用的是C

答案 2 :(得分:2)

对于初学者,您展示的代码不是有效的C代码。您正在使用C ++元素。所以程序甚至不会编译为C程序。

由于函数可以更改最初设置为start的节点NULL,您必须通过引用传递它。否则,函数参数linkedlist是函数的局部变量,将在函数中更改,最后在退出函数后将被销毁。因此原始指针start本身不会被更改。

另外这个代码块

    else {
        new_element->next = (linkedlist)->next;
        (linkedlist)->next = new_element;
    }

错了。此代码块不会在列表的开头插入新节点。它在第一个已经存在的节点之后插入一个新节点。

考虑到函数名append不适合在列表的开头插入节点。最好将其命名为insert。 该功能可以按以下方式查看

int insert( struct node **linkedlist, int data )
{
    struct node *new_element = malloc( sizeof( struct node ) );
    int success = new_element != NULL;

    if ( success )
    {
        new_element->data = data;
        new_element->next = *linkedlist;
        *linkedlist = new_element;
    }

    return success;
}

如果确实需要一个将节点附加到列表的函数,那么它可以采用以下方式

int append( struct node **linkedlist, int data )
{
    struct node *new_element = malloc( sizeof( struct node ) );
    int success = new_element != NULL;

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

        while ( *linkedlist != NULL ) linkedlist = &( *linkedlist )->next; 
        *linkedlist = new_element;
    }

    return success;
}

这是一个示范程序

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

struct node 
{
    int data;
    struct node* next;
} *start = NULL;

int insert( struct node **linkedlist, int data )
{
    struct node *new_element = malloc( sizeof( struct node ) );
    int success = new_element != NULL;

    if ( success )
    {
        new_element->data = data;
        new_element->next = *linkedlist;
        *linkedlist = new_element;
    }

    return success;
}

int append( struct node **linkedlist, int data )
{
    struct node *new_element = malloc( sizeof( struct node ) );
    int success = new_element != NULL;

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

        while ( *linkedlist != NULL ) linkedlist = &( *linkedlist )->next; 
        *linkedlist = new_element;
    }

    return success;
}

void printList( struct node* linkedlist )
{
    if ( linkedlist == NULL ) 
    {
        puts( "Linked list is empty" );
    }
    else 
    {
        for ( struct node *current = linkedlist; current != NULL; current = current->next ) 
        {
            printf( "%d ", current->data );
        }
        printf( "\n" );
    }
}

int main( void ) 
{
    const int N = 10;

    for ( int i = 1; i <= N; i++ )
    {
        if ( i % 2 == 0 ) append( &start, i );
        else insert( &start, i );
    }

    printList( start );

    return 0;
}

它的输出是

9 7 5 3 1 2 4 6 8 10

答案 3 :(得分:0)

在追加功能中你应该

  1. 首先将newnode的下一个初始化为null
  2. 在插入空列表前检查,如果为空,则将其作为头部。
  3. 如果它不为空,则将新节点指向列表的头部并使其成为新的头部。
  4. 为了反映在追加中完成的插入,你应该从函数中返回修改后的头部(也相应地修改main)。
  5. 看看这段代码: -

        node *append(node *linkedlist,int data){
            node *new_element=NULL;
            new_element=(node *)malloc(sizeof(struct node));
            new_element->data=data;
            new_element->next=NULL;// initialise next of newnode to  be null here
            // In case of empty list make this as first node
            if(linkedlist==NULL)
            {
                  linkedlist=new_element;
            }
           else
            {
                new_element->next=(linkedlist);//point the new node to head of list
                (linkedlist)=new_element;// make new node as head
            }
            return linkedlist;
        }
    
    
        int main()
        {
            start = append(start, 4);
            start = append(start, 5);
            printList(start);
        }
    

答案 4 :(得分:0)

我不认为你的if语句是正确的。我会这样做

<?php if ($row['Status'] == 'In Process'):?>                                    
    <span class="badge" style="background-color:#67A6DF">In Process</span>                                  
<?php endif; ?>
<?php if ($row['Status'] == 'Test'): ?>
    <span class="badge" style="background-color:#FCB529">In Test</span>
<?php endif;?>
<?php if ($row['Status'] == 'Approved'):?>
    <span class="badge" style="background-color:#43A995">Approved</span>                                                            
<?php endif;?>

答案 5 :(得分:0)

在C中传递参数时,它会为要使用的函数创建本地副本。修改函数内部的参数时,只会更改本地副本。

void f1( int a )
{
    a = 1; // modification does not affect the calling function
}

int b=0;
f1( b );
assert( b == 0 ); // b was not changed by f

在C(或C风格的C ++)中,如果你想要一个函数修改参数,你需要将它作为指针传递:

void f2( int * a )
{
    (*a) = 1;
}

int b=0;
f2( &b );
assert( b == 1 ); // b was changed by f

如果该参数已经是指针类型,则需要将其作为指针传递给指针:

void f3( int * * a )
{
    (*a) = (int*) malloc(sizeof(int));
    (**a) = 1;
}

int * b = NULL;
f3( &b );
assert( b != NULL ); // the pointer was initialized
assert( *b == 1 ); // the pointed-to value was initialized

在C ++中,赋值过程可以稍微简单一些,因为您可以使用reference parameters而不是显式指定指针。