在C中实现双向链表

时间:2015-03-14 04:03:47

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

每当调用insertAtBeginning方法时,我想在链表的开头插入一个节点。我的代码构建良好,但我没有得到所需的输出。

我得到以下输出:

0------>NULL

所需的输出是:

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

以下是我的代码:

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

struct dll{
    int data;
    struct dll* previous;
    struct dll* next;
};


struct dll* insertAtBeginning(int a, struct dll* head){

    if(head == NULL){
        head->data = a;
        head->previous = NULL;
        head->next = NULL;
        return head;
    }
    else{
        struct dll *first;
        first = (struct dll*) malloc( sizeof(struct dll));
        first->data = a;
        first->next = head;
        head->previous = first;
        first->previous = NULL;
        head = first;
        free(first);
        return head;
    }
}


void display_from_first(struct dll* head){
    struct dll *temp;
    temp = head;

    printf("\nThe linked list contains: ");
    while(temp != NULL) {
        printf("%d------>",temp->data);
        temp = temp->next;
    }
    printf("NULL\n");
    free(temp);
    }


int main(){
    int i = 0;
    struct dll *head1, *tail1;
    head1 = (struct dll*) malloc( sizeof(struct dll));
    head1->next = NULL;
    head1->previous = NULL;

    for(i=0; i<10; i++){
        insertAtBeginning(i, head1);
    }

    display_from_first(head1);

    return 0;
}

4 个答案:

答案 0 :(得分:3)

如果您从两个节点的空列表开始,双链表的代码会更清晰。如下所示。

enter image description here

这样您就不必处理if(head==NULL)等特殊情况。在插入(或删除)节点之前和之后总会有一个节点,所以你只需要连接起来就可以了。

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

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

Node *insertAtBeginning( Node *head, int value )
{
    // allocate memory for the new node
    Node *node = malloc( sizeof(Node) );
    if ( node == NULL )
        return NULL;

    // insert the node at the beginning of the list
    Node *temp = head->next;
    head->next = node;
    temp->prev = node;

    // fill in the fields of the node
    node->prev = head;
    node->next = temp;
    node->data = value;

    return node;
}

void showList( Node *head )
{
    Node *node;

    printf( "The list contains: " );
    for ( node = head->next; node->next != NULL; node = node->next )
        printf( "%d--->", node->data );
    printf( "NULL\n" );
}

int main( void )
{
    // create an empty list with two nodes
    Node head = { NULL , NULL, 0 };
    Node tail = { &head, NULL, 0 };
    head.next = &tail;

    // insert more nodes
    for ( int i = 0; i < 10; i++ )
        insertAtBeginning( &head, i );

    // display the list
    showList( &head );
}

答案 1 :(得分:2)

free(first);中无法insertAtBeginning()

代码here.

顺便提一下,如果您有空列表,则display_from_first()打印The linked list contains: 0------>NULL因为

head1 = (struct dll*) malloc( sizeof(struct dll));
head1->next = NULL;
head1->previous = NULL;
main()中的

。将其从主要设备中删除以获得正确的输出

答案 2 :(得分:2)

你有几个错误。

1)您的函数insertAtBeginning返回指向已更改列表的指针,但您不会在主函数中更新指向列表头的指针。

2)您正在释放插入函数中刚刚分配的指向新节点的指针。你认为你正在释放指针,但实际上你说在内存中这个地方不需要更多,所以你的节点不能存在。

答案 3 :(得分:2)

这里主要有两个问题:

  1. free(first):这不是必需的,因为您希望保存刚刚分配的内存,而不是删除它。

  2. 您的insertAtBeginning()函数会返回指向head的指针,因此在main()中,您调用此函数的位置会将其更改为head1=insertAtBeginning(i, head1);这样您的头部就是也保存了。

  3. 以下是两次编辑的代码:

    http://ideone.com/nXwc8z