C语言实现双向循环链表

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

struct list_head {
     struct list_head *next, *prev;
};

#define list_entry(ptr, type, member)           (type *)( (char *)ptr - ((size_t) &((type *)0)->member))

#define list_for_each(pos, head)      for (pos = (head)->next; pos != (head); pos = pos->next)

#define list_for_each_safe(pos, n, head)     for (pos = (head)->next, n = pos->next; pos != (head);         pos = n, n = pos->next)

static inline void INIT_LIST_HEAD(struct list_head *list)
{
    list->next = list;
    list->prev = list;
}

static inline void list_add_tail(struct list_head *new_node, struct list_head *head)
{
    new_node->next = head;
    new_node->prev = head->prev;
    head->prev->next = new_node;
    head->prev = new_node;
} 

static inline void list_del(struct list_head *entry)
{
     entry->next->prev = entry->prev;
     entry->prev->next = entry->next;
     entry->next = NULL;
     entry->prev = NULL;
}

static inline int list_empty(const struct list_head *head)
{
    return head->next == head;
}

//使用例子
struct stu {
    int num;
    char name[20];
    struct list_head list;
};

int main(void)
{
    struct stu *list_node = NULL;
    struct list_head *pos = NULL,*n = NULL;
    struct stu *pnode = NULL;

    struct stu *head = (struct stu *)malloc(sizeof(struct stu));
    if (head == NULL) {
        printf("file,%s line,%d:malloc error!\n",__FILE__,__LINE__);
        exit(1);
    }

    INIT_LIST_HEAD(&head->list);

    list_node = (struct stu *)malloc(sizeof(struct stu));
    if (list_node == NULL) {
        printf("file,%s line,%d:malloc error!\n",__FILE__,__LINE__);
        exit(1);
    }

    list_node->num = 0;
    strcpy(list_node->name,"xiaoming");
    list_add_tail(&list_node->list,&head->list);

    list_node = (struct stu *)malloc(sizeof(struct stu));
    if (list_node == NULL) {
        printf("file,%s line,%d:malloc error!\n",__FILE__,__LINE__);
        exit(1);
    }

    list_node->num = 1;
    strcpy(list_node->name,"xiaohua");
    list_add_tail(&list_node->list,&head->list);

    if (list_empty(&head->list)) {
        printf("list is empty!\n");
    } else {
        list_for_each(pos,&head->list) {
            pnode = list_entry(pos,struct stu,list);
            printf("num:%d,name %s\n",pnode->num,pnode->name);
        }
    }

    list_for_each_safe(pos,n,&head->list) {
        list_del(pos);
        pnode = list_entry(pos,struct stu,list);
        printf("num %d has removed from the list!\n",pnode->num);
    }   free(pnode);

    free(head);
    return 0;
}

  

时间: 2024-10-14 02:29:13

C语言实现双向循环链表的相关文章

C语言通用双向循环链表操作函数集

说明 相比Linux内核链表宿主结构可有多个链表结构的优点,本函数集侧重封装性和易用性,而灵活性和效率有所降低.     可基于该函数集方便地构造栈或队列集.     本函数集暂未考虑并发保护. 一  概念 链表是一种物理存储单元上非连续.非顺序的存储结构,数据元素的逻辑顺序通过链表中的指针链接次序实现.链表由一系列存储结点组成,结点可在运行时动态生成.每个结点均由两部分组成,即存储数据元素的数据域和存储相邻结点地址的指针域.当进行插入或删除操作时,链表只需修改相关结点的指针域即可,因此相比线性

C语言实现双向非循环链表的逆序打印

我在上一篇博客中<C语言实现双向非循环链表>实现了如何构造一个双向非循环链表,并实现了正向打印.我还在之前一篇博客<C语言实现单链表的逆序打印>中实现了单链表的逆序打印.这篇博客我们来实现对双向非循环链表进行逆序打印,实现起来非常的简单.代码已经上传至 https://github.com/chenyufeng1991/ReverseDoubleLinkedList . 核心代码如下: //打印非循环双向链表,这个其实是正向打印 void printList(Node *pNode

C语言实现双向非循环链表的节点插入

我在之前一篇博客中<C语言实现双向非循环链表的逆序打印>讲到了如何逆序输出一个双向非循环链表,让我们对这种链表类型有了理性的认识.今天我们要来实现的是对双向非循环链表进行节点的插入.大家可以和<C语言实现单链表节点的插入>单链表的节点插入对比着学习.代码上传至  https://github.com/chenyufeng1991/InsertDoubleLinkedList . 核心代码如下: Node *InsertList(Node *pNode,int pos,int x){

双向循环链表(C语言描述)(四)

下面以一个电子英汉词典程序(以下简称电子词典)为例,应用双向循环链表.分离数据结构,可以使逻辑代码独立于数据结构操作代码,程序结构更清晰,代码更简洁:电子词典的增.删.查.改操作分别对应于链表的插入.删除.查找.查找和获取链表元素操作. 在程序初始化时,除了初始化链表,还要将保存在文件中的词库加载到链表中: 1 void dict_init() { 2 list = linkedlist_new(); 3 4 dict_load(); 5 printf("Welcome."); 6 }

C语言实现双向非循环链表(带头结点尾结点)的节点插入

对于双向链表,个人推荐使用带头结点尾结点的方式来处理会比较方便.我在<C语言实现双向非循环链表(不带头结点)的节点插入>中详细实现了在不带头结点的情况下的插入.这次我们将会来在使用头结点尾结点的情况下在任意的位置插入元素.代码上传至 https://github.com/chenyufeng1991/InsertNodeDoubleLinkedList_HeadNode . 核心代码如下: //插入一个节点 //插入位置分别为0,1,2,..... int InsertNodeList(Nod

C语言双向循环链表api(源自gluster源码)

C语言双向循环链表api(源自gluster源码)基本的操作如增加.删除和遍历等 #include <stdio.h> #include <stdlib.h> #include <string.h> /*定义表头*/ struct list_head { struct list_head *next; struct list_head *prev; }; /*表头初始化*/ #define INIT_LIST_HEAD(head) do { (head)->nex

c语言编程之双向循环链表

双向循环链表就是形成两个环,注意每个环的首尾相连基本就可以了. 程序中采用尾插法进行添加节点. 1 #include<stdio.h> 2 #include<stdlib.h> 3 #define element int 4 typedef struct Node{ 5 element data; 6 struct Node *next; 7 struct Node *prior; 8 }*pNode; 9 10 //build a new double loop list 11

c语言双向循环链表

双向循环链表,先来说说双向链表,双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱.所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点.而循环链表之前也有说过,单链表中就是让最后一个结点的指针指向第一个结点就能构成一个循环链表,这里其实也是一样的,只不过多了一步,让第一个结点的前驱指向最后一个结点就行了,(这里介绍的是带头结点的双向循环链表,所以用第一个结点和头结点来区分两者).下面直接看看怎么创建一个带头结点的双向循环链表吧

C语言双向循环链表实现及图示(初始化/插入链表/清空/销毁)

-------------------------------------------- 双向循环链表 //遍历等执行方法与普通双向链表相同,不单独列举 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 初始化+尾插法 图示: 实现代码 1 /* 初始化