如何使用C将值插入双向链表

时间:2019-10-10 23:49:03

标签: c doubly-linked-list

我只是想在C中将值插入到已排序的双向链表中。 当我使用以下命令将其打印出来时,它永远不会显示新创建的节点。我创建了一个新节点,然后设置了值,然后更新了新节点及其前面的节点的上一个指针和下一个指针。我确定它与通过引用有关,并且想了解为什么?

struct NodeType {
int data;
struct NodeType * prev;
struct NodeType * next;
}*head, *last;

void insert_double(int key);
void displayList();
void find_node(int key);


int main()
{

head = NULL;
last = NULL;
/* Create a list with one as value and set as head */
head = (struct NodeType *)malloc(sizeof(struct NodeType));
head->data = 3;
head->prev = NULL;
head->next = NULL;
last = head;

int value=1;

insert_double(value);
printf("0\n");
displayList();
printf("1\n");
value=2;
printf("2\n");
find_node(value);
printf("3\n");
displayList();

return 0;

}

void displayList()
{
struct NodeType * temp;
int n = 1;

if(head == NULL)
{
    printf("List is empty.\n");
}
else
{
    temp = head;
    printf("DATA IN THE LIST:\n");

    while(temp != NULL)
    {
        printf("DATA of %d node = %d\n", n, temp->data);

        n++;

        /* Move the current pointer to next node */
        temp = temp->next;
    }
}
}

void find_node(int key)
{
struct NodeType * temp;
struct NodeType * newnode;
newnode->data=key;
 if(head == NULL){
    printf("No nodes");
}
else{
    temp=head;
    while(temp!=NULL)
    {
        if((temp->data)< key){
            newnode->prev=temp->prev;
            newnode->next=temp;
            temp->prev=newnode;
            break;
        }
        else{
            temp=temp->next;
        }
    }

}


}

void insert_double(int key)
{
struct NodeType * newnode;

if(head == NULL)
{
    printf("Empty!\n");
}
else
{
    newnode = (struct NodeType *)malloc(sizeof(struct NodeType));

    newnode->data = key;
    newnode->next = head; // Point to next node which is currently head
    newnode->prev = NULL; // Previous node of first node is NULL

    /* Link previous address field of head with newnode */
    head->prev = newnode;

    /* Make the new node as head node */
    head = newnode;

}
}

3 个答案:

答案 0 :(得分:0)

您的代码基本上是正确的。在处理链表时,您仅缺少两个重要的极端情况。首先是当您使用find_node插入一些值时,它将被添加到列表的开头。在这种情况下,您新创建的节点将成为列表的新头,因此您必须更新head变量。第二种情况是相反的,当您将新节点插入列表的末尾时会发生这种情况。然后它成为列表的结尾,因此您需要更新tail

在第一次使用链表时,会遗漏这两种情况,所以请不要担心。我认为几乎每个使用链表的人都在旅途的开始就犯了这些错误。

此外,您正在使用指向NodeTypefind_node结构的未初始化指针:

struct NodeType * newnode;

应该是:

struct NodeType * newnode = (struct NodeType *)malloc(sizeof(struct NodeType));

答案 1 :(得分:0)

感谢你们俩。这是我根据您的两次输入提出的解决方案:

void insert_sorted_node(int key){
struct NodeType * temp = (struct NodeType *)malloc(sizeof(struct NodeType));
struct NodeType * newnode = (struct NodeType *)malloc(sizeof(struct NodeType));
newnode->data=key;
/* no nodes at all*/
/* insert_sorted_node(value) can't start empty list, need to fix */
 if(head == NULL){
    printf("head =null");
    temp = head;
    head->data=key;
    head->prev=NULL;
    head->next=NULL;
    last = head;
}
else{
    temp=head;
    while(temp!=NULL)
    {
        printf("\n\ndata = %d\nkey = %d\n", temp->data, key);

        /* key is new head 
            1) check if key < head->data

        */
        if(key<head->data)
        {
            printf("\nnew head\n");
            newnode->prev = head->prev;
            newnode->next = temp;
            temp->prev = newnode;
            head = newnode;
            break;

        }

        /* key is tail 
            if temp->next = NULL
        */
        else if(temp->next == NULL)
        {
            printf("\ntail\n");
            newnode->prev = temp;
            newnode->next = NULL;
            temp->next = newnode;
            last = newnode;
            break;
        }

        /* key is middle head 
            if key > temp->data and key< temp->next->data 

        */
        else if((key>temp->data)&&(key<temp->next->data))
        {
            printf("\nmiddle\n");
            newnode->prev=temp;
            newnode->next=temp->next;
            temp->next=newnode;
            temp->next->prev=newnode;
            break;
        }


        else{
            printf("next\n");
            temp=temp->next;
        }
    }



}


 }

答案 2 :(得分:-1)

您的插入功能和displayList一样正常。

但是,该程序在find_node函数中具有未定义的行为:

void find_node(int key)
{
    struct NodeType * temp;
    struct NodeType * newnode;
    newnode->data=key;            //<-- BOOM! (writing to uninitialized pointer)

    if(head == NULL){
        printf("No nodes");
    }
    else{
        temp=head;
        while(temp!=NULL)
        {
            if((temp->data)< key){
                newnode->prev=temp->prev; //<-- BOOM!
                newnode->next=temp;       //<-- BOOM!
                temp->prev=newnode;
                break;
            }
            else{
                temp=temp->next;
            }
        }
    }
}

目前尚不清楚您要达到的目标。如果这确实是一个 find 函数,则不应尝试在节点上执行操作或复制任何数据。

您真正需要的是这样的东西:

struct NodeType* find_node(int key)
{
    for(struct NodeType* temp = head; temp != NULL; temp = temp->next)
    {
        if (temp->data == key)
            return temp;
    }
    return NULL;
}
相关问题