循环链表是单链表的变形。
循环链表最后一个结点的 link 指针不 为NULL,而是指向了表的前端。(指向头结点)
为简化操作,在循环链表中往往加入表头结点。
循环链表的特点是:只要知道表中某一结点的地址,就可搜寻到所有其他结点的地址。
结构特点:
头文件
#ifndef CIRCLEDOUBLELINKLIST_H
#define CIRCLEDOUBLELINKLIST_H
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <time.h>
7
8 #define SUCCESS 10000
9 #define FAILURE 10001
10
11 typedef int ElemType;
12
13 struct Node
14 {
15 ElemType data;
16 struct Node *next;
17 struct Node *prior;
18 };
19 typedef struct Node node;
20 typedef struct Node *pNode;
21
22 int InitLink(pNode *h);
23 int InsertLink(pNode h, int p, int num);
24 int TraverseLink(pNode h);
25 int GetElem(pNode h, int p);
int LocateElem(pNode h, int e);
27 int LengthLink(pNode h);
28 int PriorElem(pNode h, int num);
29 int NextElem(pNode h, int num);
30 void ReverseLink(pNode h);
31 int LinkDel(pNode h, int p);
32 int ClearLink(pNode h);
33 int DestroyLink(pNode *h);
34
35 #endif
子函数调用函数,函数文件
#include"DoubleLinkList.h"
int InitLink(pNode *h)
{
if(NULL == h)
return FAILURE;
*h = (pNode)malloc(sizeof(pNode) * 1);
if(NULL == *h)
return FAILURE;
(*h) -> next = *h;
(*h) -> prior = *h;
return SUCCESS;
}
int InsertLink(pNode h, int p, int num)
{
if(NULL == h)
return FAILURE;
pNode t = h;
int k = 1; //指针移动的次数
while(k < p)
{
t = t -> next;
if(t == h)
{
return FAILURE;
}
k++;
}
if( k > p )
return FAILURE;
pNode n = (pNode)malloc(sizeof (pNode) *1);
if(NULL == n)
{
return FAILURE;
}
n-> data = num;
n-> next = t ->next;
n -> prior = t;
t -> next = n;
if(n -> next)
{
t -> next -> prior = n;
}
return SUCCESS;
}
int Traverse(pNode h)
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
while(t != h)
{
printf("%d\n", t -> data);
t = t -> next;
}
printf("\n");
return SUCCESS;
}
int GetElem(pNode h, int p);
{
if(NULL == h)
return FAILURE;
if(p <= 0)
return FAILURE;
pNode t = h ;
int k = 0;
while(k < p )
{
t = t -> next;
if(t == h)
{
return FAILURE;
}
k++;
}
int e = t -> data;
return e;
}
int LocateLink(pNode h, int e)
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
int k = 1;
while(t != h)
{
if(t -> data == e)
{
return i;
}
t = t ->next;
i++;
}
return FAILURE;
}
int LengthLink(pNode h);
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
int i = 1;
while(t != h)
{
t = t -> next;
i++;
}
return i - 1;
}
int PriorElem(pNode h, int num)
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
while(t != h)
{
if(num == t ->data)
{
return t ->prior -> data;
}
t = t -> next;
}
if(t == h) //只有一个结点
{
return FAILURE;
}
return FAILURE;
}
int NextElem(pNode h, int num)
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
while(t -> next != h)
{
if(num == t -> data)
{
return t -> next -> data;
}
t = t ->next ;
}
return FAILURE;
}
#if 0
void ReverseLink(pNode h);
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
h -> next = NULL;
int i = 0;
while(t)
{
pNode q = p;
p = p -> next;
q -> next = h -> next;
q -> prior = h ;
h -> next = q;
}
if(0 != i)
{
q -> next -> prior = q;
i++;
}
}
#endif
int LinkDel(pNode h, int p)
{
if(NULL == h)
return FAILURE;
pNode t = h ;
int k = 1;
while( k < p)
{
t = t -> next;
if(t == h)
{
return FAILURE;
}
k++;
}
if(k > p|| t -> next == h ) //p的值太小 无法删除最后的下一个结点
{
return FAILURE;
}
pNode n = t -> next;
int e = n -> data;
t -> next = n -> next;
n -> next ->prior = t;
free(n);
return e;
}
int ClearLink(pNode h)
{
if(NULL == h)
return FAILURE;
pNode t = h -> next;
while(t != h)
{
h -> next = t -> next; //头结点指向第二个节点
t -> next ->prior = h;
free(t); //释放这个位置的元素的空间
t = t ->next; //接着指向下一个结点,进行下一次循环
}
return SUCCESS;
}
int DestoryLink(pNode *h)
{
if(NULL == h)
return FAILURE;
free(*h);
*h = NULL;
return SUCCESS;
}
主函数文件
#include "LinkList.h"
int main()
{
srand (time (NULL)); //随机时间随机数字函数
pNode head = NULL; //定义链表的头指针
int ret ;
//链表初始化
ret = InitLink(&head);
if(SUCCESS == ret)
{
printf("链表初始化成功\n");
}
else
{
printf("链表初始化失败!\n");
}
//指定位置插入元素(这里是去全插入,相当于把数据传给链表)
int i, num;
for (i =0; i < 7; i++)
{
num = rand () %10;
ret = InsertLink(head, i+1, num); // 尾插法
// ret = InsertLink(head, 1, num); //头插法
if (FAILURE == ret)
{
printf("插入元素%d失败\n". num);
}
else
{
printf("插入元素%d成功\n", num);
}
}
// 根据位置查找元素
int p = 6;
ret = GetElem(head, p); //获取指定元素的位置
if (FAILURE == ret)
{
printf("第%d个元素不存在\n", p);
}
else
{
printf("第%d个元素是%d\n", p, ret);
}
//根据元素查找位置
num = 6;
ret = LocateElem(head, num); //返回指定元素的位置
if(FAILURE == ret)
{
printf("元素%d不存在\n", num);
}
else
{
printf("元素%d是第%d个元素\n", num);
}
printf("链表的长度是%d\n", LengthLink(head));
//根据元素查找元素的前驱
num = 6;
ret = PriorElem (head, num); //返回指定元素的前驱
if(FAILURE == ret)
{
printf("%d没有前驱\n", num);
}
else
{
printf("%d的前驱是%d\n", num, ret);
}
//根据元素查找元素的后继结点
num = 6;
ret = NextElem(head, num);
if(FAILURE == ret)
{
printf("%d没有后继结点\n", num);
}
else
{
printf("%d的后继结点是%d\n", num, ret);
}
//删除指定位置的元素
for(i = 0; i < 3; i++)
{
p = rand() %4; //随机产生一个位置
ret = LinkDel(head, p);
if(FAILURE == ret)
{
printf("删除第%d个元素失败\n", p);
}
else
{
prinntf("删除第%d个结点成功,元素是%d\n", p , ret);
}
}
//清空链表
ret = ClearLink(head);
if(FAILURE == ret)
{
printf("清空链表失败\n");
}
else
{
printf("清空链表成功\n");
}
//销毁链表
ret = DestoryLink(&head);
if(FAILURE == ret)
{
printf("清除失败\n");
}
else
{
printf("清除成功\n");
}
return 0;
}