c语言双向循环链表

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

 1 #include<stdio.h>
 2 #include<stdlib.h>
 3 struct data
 4 {
 5     int num;
 6     struct data *front;                                        //指向它之前的结点
 7     struct data *next;                                        //指向它之后的结点
 8 };
 9 int main()
10 {
11     int n=1;
12     struct data *p,*p1,*head;
13     p=head=(struct data *)malloc(sizeof(struct data));    //创建一个带头结点的双向循环链表
14     p->next=NULL;                                        //开始的时候把指向前面的和后面的指针都置为空
15     p->front=NULL;
16     p1=(struct data *)malloc(sizeof(struct data));        //创建新结点,向链表中添加数据
17     p1->num=1;
18     while(n<=10)
19     {
20         n++;
21         p->next=p1;                                        //让前一个结点p的尾指针指向这个结点p1
22         p1->front=p;                                    //这个结点的头指针指向前一个结点
23         p=p1;                                            //p1变为p
24         p1=(struct data *)malloc(sizeof(struct data));    //创建新的结点p1,给其赋值并重复上面的循环
25         p1->num=n;
26     }
27     p->next=head->next;                                //最后,由于是带头结点的双循环链表,所以要让最后一个结点的尾指针指向head之后的那个结点
28     head->next->front=p;                            //让head之后的那个结点的头指针指向尾结点
29     free(p1);
30     return 0;
31
32 }

双向循环链表可以随时访问任何一个结点的前一个结点,所以,用来查找会很方便.它的删除和添加和单链表的操作差不多,只不过需要注意,有两个指针域,要分别让他们重新指向新的结点.还有一点需要注意,就是如果要删除的结点是第一个结点的话,需要让头结点重新指向.来一小段代码吧

 1 while(1)                        //循环寻找需要删除的结点
 2     {
 3         if(p->num==5)                    //寻找的条件
 4         {
 5             if(head->next==p)            //判断删除的结点是不是第一个结点
 6             {
 7                 head->next=p->next;        //如果是第一个结点,让头结点指向它之后的结点
 8             }
 9             p->front->next=p->next;            //当前结点的前一个结点为p->front,让它指向当前结点的下一个结点p->next
10             p->next->front=p->front;        //让当前结点p的下一个结点p->next的前驱指向它的前一个结点p->front;这样就删掉了这个结点
11             break;
12         }
13         p=p->next;
14
15     }

OK,好好加油! ! ! ^_^

时间: 2024-11-01 11:17:43

c语言双向循环链表的相关文章

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 /* 初始化

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

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

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

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

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语言版

源文件部分: #include<stdio.h> #include<string.h> #include<malloc.h> typedef int Elemtype; #include"Delist.h" int main() { Dlnode head=NULL; instruction(head); return 0; } 头文件部分: typedef struct DLnode { Elemtype data; struct DLnode *

数据结构8: 双向链表(双向循环链表)的建立及C语言实现

之前接触到的链表都只有一个指针,指向直接后继,整个链表只能单方向从表头访问到表尾,这种结构的链表统称为 “单向链表”或“单链表”. 如果算法中需要频繁地找某结点的前趋结点,单链表的解决方式是遍历整个链表,增加算法的时间复杂度,影响整体效率.为了快速便捷地解决这类问题,在单向链表的基础上,给各个结点额外配备一个指针变量,用于指向每个结点的直接前趋元素.这样的链表被称为“双向链表”或者“双链表”. 双链表中的结点 双向链表中的结点有两个指针域,一个指向直接前趋,一个指向直接后继.(链表中第一个结点的

1.Go-copy函数、sort排序、双向链表、list操作和双向循环链表

1.1.copy函数 通过copy函数可以把一个切片内容复制到另一个切片中 (1)把长切片拷贝到短切片中 package main import "fmt" func main() { s1 := []int {1,2} s2 := []int{3,4,5,6} //copy的是角标,不会增加元切片的长度 copy(s1,s2) fmt.Println(s1) //[3 4] fmt.Println(s2) //[3 4 5 6] } (2)把短切片拷贝到长切片中 package ma

第33课 双向循环链表的实现

1. DTLib中双向链表的设计思路 (1)数据结点之间在逻辑上构成双向循环,这有别于Linux内核链表的实现. (2)头结点仅用于结点的定位,而Linux内核链表是将头结点作为循环的一部分. 2. 实现思路 (1)通过模板定义DualCircleList类,继承自DualLinkList类 (2)在DualCircleList内部使用Linux内核链表进行实现(另类实现) (3)使用struct list_head定义DualCircleList的头结点 (4)特殊处理:循环遍历时忽略头结点