循环链表
来源:互联网 发布:会计核算软件版本号 编辑:程序博客网 时间:2024/05/16 14:45
资料来源:
http://student.zjzk.cn/course_ware/data_structure/web/xianxingbiao/xianxingbiao2.3.2.htm点击打开链接
循环链表(Circular Linked List)
循环链表是一种首尾相接的链表。
1、循环链表
(1)单循环链表——在单链表中,将终端结点的指针域NULL改为指向表头结点或开始结点即可。
(2)多重链的循环链表——将表中结点链在多个环上。
2、带头结点的单循环链表
注意:
判断空链表的条件是head==head->next;
3、仅设尾指针的单循环链表
用尾指针rear表示的单循环链表对开始结点a1和终端结点an查找时间都是O(1)。而表的操作常常是在表的首尾位置上进行,因此,实用中多采用尾指针表示单循环链表。带尾指针的单循环链表可见下图。
注意:
判断空链表的条件为rear==rear->next;
4、循环链表的特点
循环链表的特点是无须增加存储量,仅对表的链接方式稍作改变,即可使得表处理更加方便灵活。
【例】在链表上实现将两个线性表(a1,a2,…,an)和(b1,b2,…,bm)连接成一个线性表(a1,…,an,b1,…bm)的运算。
分析:若在单链表或头指针表示的单循环表上做这种链接操作,都需要遍历第一个链表,找到结点an,然后将结点b1链到an的后面,其执行时间是O(n)。若在尾指针表示的单循环链表上实现,则只需修改指针,无须遍历,其执行时间是O(1)。
相应的算法如下:
LinkList Connect(LinkList A,LinkList B)
{//假设A,B为非空循环链表的尾指针
LinkList p=A->next;//①保存A表的头结点位置
A->next=B->next->next;//②B表的开始结点链接到A表尾
free(B->next);//③释放B表的头结点
B->next=p;//④
return B;//返回新循环链表的尾指针
}
注意:
①循环链表中没有NULL指针。涉及遍历操作时,其终止条件就不再是像非循环链表那样判别p或p->next是否为空,而是判别它们是否等于某一指定指针,如头指针或尾指针等。
②在单链表中,从一已知结点出发,只能访问到该结点及其后续结点,无法找到该结点之前的其它结点。而在单循环链表中,从任一结点出发都可访问到表中所有结点,这一优点使某些运算在单循环链表上易于实现。
5、循环链表的其它几个操作
循环链表的插入、删除和获取元素的操作基本和单链表类似。
具体实践代码:
#include <stdio.h>#include <stdlib.h>typedef struct Node{int data;struct Node* next;}Node,*CirculateList;//create circulate list with n elements.CirculateList CreateList(CirculateList list, int n){CirculateList temp,head;list = (Node*)malloc(sizeof(Node*));if(list == NULL){printf("fails to create list.\n ");return NULL;}head = list;head ->next = head; //empty listint i = 1;while(i <= n){temp = (Node*)malloc(sizeof(Node*));if (1==i){temp->next=head;}else{temp->next = list->next;}temp->data = i;list->next = temp;++i;}return head;}//1 ture;0errorint ListInsert(CirculateList list, int pos, int num){CirculateList temp,node;temp = list;int i=1;while(temp->next!=list){if (i==pos){break;}temp = temp->next;i++;}if((list==temp->next)&&(i<pos)){printf("fails to insert %d into list.\n ",num);return 0;}else if((list==temp->next)&&(i==pos)){node = (Node*)malloc(sizeof(Node*));temp->next = node;node->data = num;node->next = list;}else{node = (Node*)malloc(sizeof(Node*));node->next = temp->next;temp->next = node;node->data = num;}return 1;}//1 ture;0errorint ListDelete(CirculateList list, int pos){CirculateList temp,node;node = (Node*)malloc(sizeof(Node*));temp = list;int i=1;while(temp->next!=list){ temp = temp->next;if (i==pos){break;}i++;}if((list==temp->next) && (i<pos)){printf("fails to delete a element from list at pos %d.\n ",pos);return 0;}else{node= temp->next;temp->data = node->data;temp->next = node->next;//free(node);}return 1;}//return the pos of element. 0 instands None exist.int LocateElem(CirculateList list, int element){CirculateList p = list->next->next; int j = 1; while (p != list->next) {++j;if (p->data == element)return j;p = p->next;} return 0;}void ListShow(CirculateList list){if(list->next == list){printf("No elements in the list.\n");}else{CirculateList temp;temp = (Node*)malloc(sizeof(Node*));temp=list->next;while(temp!=list){printf("%d ", temp->data);temp = temp->next;}printf("\n");}}int main(){CirculateList mylist;mylist = CreateList(mylist, 16);ListShow(mylist);printf("---------------------------------------------\n");int ret = ListInsert(mylist, 16,18);if (!ret){printf("fail to insert list.\n");}ListShow(mylist);printf("---------------------------------------------\n");int n=18;printf("the pos of %d is %d\n",n, LocateElem(mylist, n));printf("---------------------------------------------\n");ret = ListDelete(mylist, 1);if (!ret){printf("fail to insert list.\n");}ListShow(mylist);return 0;}
- 循环链表实现循环队列
- 循环链表与循环队列
- 循环链表
- 循环链表
- 双向循环链表
- 双向循环链表
- 循环链表实验
- 链表::循环链表
- 双向循环链表
- 双向循环链表
- 循环链表
- 循环链表
- 循环链表
- 循环链表建立
- 数据结构 循环链表
- 双向循环链表
- 循环链表详解
- 循环链表
- 数据迁移[更换存储]
- Raysoft.Framework.DBUtility.AccessHelper
- CVPR 2013 录用论文(目标跟踪部分)
- 32位系统使用mongodb需要注意的几点
- CMake的安装和使用
- 循环链表
- 设置文件夹对话框的默认选中文件夹
- python的三目运算
- 深入理解C语言
- XFS文件系统在SUSE Linux下最佳调优方案
- linux 输出目录树、文件树
- php之静态变量和静态方法
- printf在终端输出时改变颜色
- jquery的each()详细介绍