简体   繁体   English

C中的双链表实现

[英]Double linked list implementation in c

I am trying to improve my c programming skills and so started with trying to program a double linked list. 我试图提高我的c编程技能,因此从尝试编写一个双链表开始。

Here is what i have come up with so far. 到目前为止,这是我想出的。

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
//forward definition

typedef struct Node node_t;


//Define the structures needed for double linked list

//Each node
typedef struct Node 
{
        int data;
        node_t *next;
        node_t *prev;
}node_t;




void initList(node_t** first , node_t** last)
{
    //Allocate memory for the first and the last node

    *first = (node_t*) malloc(sizeof(node_t));
    *last =  (node_t*) malloc(sizeof(node_t));
    (*first)->data = 1;
    (*last)->data = 2;

    (*first)->prev = NULL;
    (*last)->next = NULL;

    (*first)->next = (*last)->prev;

    return;

}

void destroyList(node_t** first)
{
    node_t* temp;

    temp = *first;

    free((*first)->next);
    free((*first));
    temp = NULL;



    return;
}



int main()
{

    node_t *first =NULL, *last = NULL;

    printf("Initalizing the List\n");
    initList(&first,&last);

    printf(" 1st element is %d\n",first->data);
    printf(" 2nd element is %d\n",last->data);

    printf("Destroying the List\n");




    destroyList(&first) ;


    return 0;
}

I actually looked up for some code online and i see that most implementations have 我实际上在网上查找了一些代码,并且看到大多数实现都有

1) 1 structure for Node and 1 structure for List itself (with head and tail). 1)Node的1个结构和List本身(带有头和尾)的1个结构。 My question is, is this mandatory? 我的问题是,这是强制性的吗? Can i not implement it with just 1 structure? 我不能只用一种结构实现它吗?

2) My idea is to make this file as a library and call it from an application. 2)我的想法是将此文件制成一个库,然后从应用程序中调用它。 Like 喜欢
InitList(), DestroyList(), AddNode, DeleteNode etc. InitList(),DestroyList(),AddNode,DeleteNode等。

And that is why i am using double pointers for the INit and destroy. 这就是为什么我在INit和destroy中使用双指针。 I am having some trouble destroying the list. 我在销毁清单时遇到了一些麻烦。 I know i am doing it wrong, i will continue to correct it. 我知道我做错了,我会继续纠正。

3) I found that node pointer 3)我发现那个节点指针

 temp = first

was pointing to some address. 指向某个地址。 If i do temp++. 如果我做temp ++。 Why doesn't it point to next node? 为什么不指向下一个节点?

4)We can either pass the first or the last node pointer to delete the entire list correct?. 4)我们可以传递第一个或最后一个节点指针来删除整个列表,对吗? ( ie traverse and dleete sequentialluy?) (即遍历和下降顺序?)

Thanks! 谢谢!

1) It's not necessary to have a list structure but it makes certain operations quicker to perform if the structure kept track of certain meta-data (length of list for example, otherwise to get length you'd have to iterate through your list every time which can be expensive for large lists). 1)不必具有列表结构,但是如果该结构跟踪某些元数据(例如列表的长度),它会使某些操作更快地执行(例如,要获取长度,则每次都必须遍历列表)对于大型列表而言可能会很昂贵)。

3) I'm assuming you mean 3)我假设你的意思是

temp = *first

and temp++ doesn't point to the next node because it's not guaranteed that your nodes are in contiguous memory addresses (arrays on the other hand do ). 并且temp ++不会指向下一个节点,因为不能保证您的节点位于连续的内存地址中(另一方面,数组会这样做)。

4) You can use first or last to delete the list but you have to ensure a certain property that previous of head also points to NULL otherwise you can get stuck in infinite loop 4)您可以使用first或last来删除列表,但必须确保head的前一个也指向NULL的某个属性,否则您将陷入无限循环

1) 1 structure for Node and 1 structure for List itself is certainly not mandatory. 1)Node的1结构和List本身的1结构当然不是强制性的。 It is often done with 1 structure. 通常用1种结构完成。

2) Nice ideas InitList(), DestroyList(), AddNode, DeleteNode etc. 2)好主意InitList(),DestroyList(),AddNode,DeleteNode等

Your init may need 您的init可能需要

(*first)->next = *last;
(*last)->prev = *first;
//  rather than
(*first)->next = (*last)->prev;

3) As @Jamil Seaidoun, do not do temp++ , rather temp = temp->next . 3)与@Jamil Seaidoun一样,不要执行temp++ ,而是temp = temp->next

4) You can pass either end. 4)您可以通过任何一端。 The classic problem is not getting the next pointer before the free() 经典的问题是没有在free()之前获取下一个指针

// bad code
free(temp);
temp = temp->next;

// good code
next = temp->next;
free(temp);
temp = next;

Ramblings 漫记

Paradigm shift. 模式转变。 Consider a double-link-list with no NULL pointers. 考虑一个没有NULL指针的双链表。 Rather make the full circle. 而是使整个圆圈。 Last->next = First . Last->next = First First->prev = Last . First->prev = Last Then instead of of while loop that goes until p->next == NULL , loop until p->next == first . 然后,而不是循环到p->next == NULL的while循环, p->next == NULL直到p->next == first The list simply points to the first node (or NULL if empty). 该列表仅指向第一个节点(如果为空,则为NULL)。 I find this style more flexible and less change of *NULL. 我发现此样式更灵活,* NULL的更改更少。

2nd Paradigm shift. 第二范式转换。 Sometimes the only reason for a double-link-list is to allow adding nodes to the beginning or the end. 有时,使用双链接列表的唯一原因是允许将节点添加到开头或结尾。 This can be accomplished with a single next field that goes around in a circle. 这可以通过绕一个圈的单个next场来完成。 The list pointer in this case does not point to the first node, but to the last. 在这种情况下,列表指针并不指向第一个节点,而是指向最后一个节点。 (note: first is last->next) Inserting at the beginning or end is the same, add a node after last and before first. (注意:first是last-> next)在开头或结尾插入相同,在last之后和first之前添加一个节点。 The difference is do we leave the list pointer as is, or advance it. 区别在于我们是将列表指针保持不变还是前进。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM