目录
一、循环单链表
1、循环单链表的定义:
2、循环单链表的优缺点:
二、循环单链表的基本操作算法(C语言)
1、宏定义
2、创建结构体
3、循环单链表的初始化
4、循环单链表的插入
5、求单链表长度
6、循环单链表的清空
7、循环单链表的销毁
8、循环单链表的取值
9、循环单链表的查找
10、循环单链表的删除
11、头插法创建循环链表
12、尾插法创建循环链表
13、输出链表元素
三、循环单链表的基本操作完整代码(C语言)
四、运行结果
一、循环单链表
1、循环单链表的定义:
循环单链表是一种特殊类型的单链表,其特点是链表的最后一个结点的指针域指向整个链表的第一个结点,从而形成一个环状结构。
这种数据结构可以用来存储有序的数据集合,其插入和删除操作可以在平均时间复杂度O(1)内完成,这是其相比单链表的一大优势。循环单链表的操作一般更复杂,因为需要维护环状的结构,并保证对链表的操作满足时间复杂度的要求。
2、循环单链表的优缺点:
优点:
- 循环单链表可以高效地执行插入和删除操作,因为不需要像单链表那样从头或尾部开始遍历整个链表。
- 循环单链表的空间利用率较高,因为最后一个结点的指针域指向整个链表的第一个结点,从而避免了浪费空间存储空指针。
- 循环单链表适合用于处理有序的数据集合,可以快速地执行查找、插入和删除操作。
缺点:
- 循环单链表的操作相对复杂,因为需要维护环状的结构,并保证对链表的操作满足时间复杂度的要求。
- 在某些情况下,循环单链表可能比单链表更难以理解和实现。
二、循环单链表的基本操作算法(C语言)
1、宏定义
#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;
2、创建结构体
typedef struct LNode {ElemType data;struct LNode *next;
} LNode, *LinkList;
3、循环单链表的初始化
//循环链表初始化
Status InitList(LinkList &head) {head = new LNode;//head->next=NULL;head->next = head;return OK;
}
4、循环单链表的插入
//插入
Status ListInsert(LinkList &head, int i, ElemType e) {LinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;j++;}if (!p || j > i - 1) {return ERROR;}LNode *s = new LNode;s->data = e;s->next = p->next;p->next = s;return OK;
}
5、求单链表长度
//求单链表长度
Status GetLinkListLength(LinkList head) {LinkList p = head->next;int length = 0;while (p != head) { //p!=NULL //单链表不为空表时length++;p = p->next;}return length;
}
6、循环单链表的清空
//清空
Status ClearLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L p!=NULLq = p;p = p->next;delete q;}head->next = head; //链表为空return OK;
}
7、循环单链表的销毁
//销毁
Status DestoryLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L p!=NULLq = p;p = p->next;delete q;}head->next = NULL;// printf("\n销毁成功\n");return OK;
}
8、循环单链表的取值
//取值
Status GetLinkList(LinkList head, int i, ElemType &e) {LinkList p = head->next;int j = 1;while (p != head && j < i) { //p != Lp = p->next;j++;}if (p == head) {//p==Lreturn ERROR;}e = p->data;return OK;
}
9、循环单链表的查找
//查找
int LocateLinkListElem(LinkList head, ElemType e) {LinkList p = head->next;int j = 1;while (p != head && (p->data != e)) {//p != L p!=NULLp = p->next;j++;}if (p == head) { //p==L !p<=>p==NULLreturn 0;}return j;
}
10、循环单链表的删除
//删除
Status ListDelete(LinkList &head, int i, ElemType &e) {LinkList p = head;int j = 0;while (p->next != head && j < i - 1) { //p != Lp = p->next;j++;}if (p->next == head) { //p==Lreturn ERROR;}LinkList q = p->next;e = q->data;p->next = q->next;delete q;return OK;
}
11、头插法创建循环链表
//头插法创建循环链表
void CreateLinkList_H(LinkList &head, int n) {InitList(head);for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;p->next = head->next;head->next = p;}
}
12、尾插法创建循环链表
//尾插法创建循环链表
void CreateLinkList_R(LinkList &head, int n) {InitList(head);LinkList r = head;for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;//p->next=NULL p->next=head//p->next = r->next;r->next = p;r = p;}r->next = head; //尾结点next域指向头结点
}
13、输出链表元素
//输出链表元素
void printLinkList(LinkList head) {LinkList p = head->next;while (p != head) { //p != Lprintf("%c", p->data);p = p->next;}printf("\n");
}
三、循环单链表的基本操作完整代码(C语言)
#include <stdio.h>
#include <conio.h>//getche()
#include <cstdlib>//free()#define OK 1
#define ERROR 0typedef char ElemType;
typedef int Status;typedef struct LNode {ElemType data;struct LNode *next;
} LNode, *LinkList;//循环链表初始化
Status InitList(LinkList &head) {head = new LNode;//head->next=NULL;head->next = head;return OK;
}//功能菜单
Status choice() {printf("==================================\n");printf(" 循环链表操作功能菜单 \n");printf("1、插入元素 2、查询表长 3、按位查找\n");printf("4、按值查找 5、删除元素 6、销毁链表\n");printf("7、清空链表 8、批量插入 9、链表元素\n");printf("10、头插法创建单链表11、尾插法创建单链表\n");printf("==================================\n");return 1;
}//插入
Status ListInsert(LinkList &head, int i, ElemType e) {LinkList p = head;int j = 0;while (p && (j < i - 1)) {p = p->next;j++;}if (!p || j > i - 1) {return ERROR;}LNode *s = new LNode;s->data = e;s->next = p->next;p->next = s;return OK;
}//求单链表长度
Status GetLinkListLength(LinkList head) {LinkList p = head->next;int length = 0;while (p != head) { //p!=NULL //单链表不为空表时length++;p = p->next;}return length;
}//销毁
Status DestoryLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L p!=NULLq = p;p = p->next;delete q;}head->next = NULL;// printf("\n销毁成功\n");return OK;
}//清空
Status ClearLinkList(LinkList &head) {LinkList p = head->next;LinkList q;while (p != head) { //p != L p!=NULLq = p;p = p->next;delete q;}head->next = head; //链表为空return OK;
}//取值
Status GetLinkList(LinkList head, int i, ElemType &e) {LinkList p = head->next;int j = 1;while (p != head && j < i) { //p != Lp = p->next;j++;}if (p == head) {//p==Lreturn ERROR;}e = p->data;return OK;
}//查找
int LocateLinkListElem(LinkList head, ElemType e) {LinkList p = head->next;int j = 1;while (p != head && (p->data != e)) {//p != L p!=NULLp = p->next;j++;}if (p == head) { //p==L !p<=>p==NULLreturn 0;}return j;
}//删除
Status ListDelete(LinkList &head, int i, ElemType &e) {LinkList p = head;int j = 0;while (p->next != head && j < i - 1) { //p != Lp = p->next;j++;}if (p->next == head) { //p==Lreturn ERROR;}LinkList q = p->next;e = q->data;p->next = q->next;delete q;return OK;
}//头插法创建循环链表
void CreateLinkList_H(LinkList &head, int n) {InitList(head);for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;p->next = head->next;head->next = p;}
}//尾插法创建循环链表
void CreateLinkList_R(LinkList &head, int n) {InitList(head);LinkList r = head;for (int i = 0; i < n; i++) {LNode *p = new LNode;//scanf("%c",&p->data);p->data = getche();//cin >> p->data;//p->next=NULL p->next=head//p->next = r->next;r->next = p;r = p;}r->next = head; //尾结点next域指向头结点
}//输出链表元素
void printLinkList(LinkList head) {LinkList p = head->next;while (p != head) { //p != Lprintf("%c", p->data);p = p->next;}printf("\n");
}int main() {LinkList list;//初始化printf("单链表正在初始化....\n");int InitStatus = InitList(list);if (InitStatus == OK) {printf("单链表初始化成功!\n");} else {printf("单链表初始化失败!\n");}choice(); //调用功能菜单函数int temp = 1; //通过改变temp的值来跳出while循环while (temp) {int flag;printf("请输入所需的功能编号:\n");scanf("%d", &flag);switch (flag) {//通过开关进行功能选择case 1: {//插入元素int insertIndex;ElemType inserElem;printf("请输入插入元素位置及插入元素(请在英文状态下输入例如:1,a): \n");scanf("%d,%c", &insertIndex, &inserElem);Status InsertS = ListInsert(list, insertIndex, inserElem);if (InsertS == OK) {printf("向循环链表%d个位置,插入元素为%c成功!\n\n", insertIndex, inserElem);} else {printf("向循环链表插入元素失败!\n\n");}}break;case 2: {//求单链表的长度int length = GetLinkListLength(list);printf("循环链表的长度为:%d。 \n\n", length);}break;case 3: {//取值Status GetIndex;printf("请输入需要查询的元素的位置:\n");scanf("%d", &GetIndex);ElemType GetElem;int GetStatus = GetLinkList(list, GetIndex, GetElem);if (GetStatus == OK) {printf("从循环链表中获取第%d位置元素成功,所获取到的元素为:%c。\n\n", GetIndex, GetElem);} else {printf("从循环链表中获取第%d位置元素失败!\n\n", GetIndex);}}break;case 4: {//查找ElemType LocateElem;printf("请输入想要查找元素:\n");getchar(); //用于接收回车scanf("%c", &LocateElem);Status LocateIndex = LocateLinkListElem(list, LocateElem);if (LocateIndex > 0) {printf("从循环链表中查找元素%c成功,它在循环链表中的位置为第%d个!\n\n", LocateElem, LocateIndex);} else {printf("从循环链表中查找元素%c失败!\n\n", LocateElem);}}break;case 5: {//删除Status DeleteIndex;printf("请输入想要删除元素的位置:\n");scanf("%d", &DeleteIndex);ElemType DeleteElem;ElemType DeleteStatus = ListDelete(list, DeleteIndex, DeleteElem);if (DeleteStatus == OK) {printf("删除循环链表第%d个位置的元素成功,删除的元素为:%c。\n\n", DeleteIndex, DeleteElem);} else {printf("删除循环链表第%d个位置的元素失败!\n\n", DeleteIndex);}}break;case 6: {//销毁Status DestoryStatus = DestoryLinkList(list);if (DestoryStatus == OK) {printf("循环链表销毁成功!\n\n");} else {printf("循环链表销毁失败!\n\n");}}break;case 7: {//清空Status ClearStatus = ClearLinkList(list);if (ClearStatus == OK) {printf("循环链表清空成功!\n\n");} else {printf("循环链表清空失败!\n\n");}}break;case 8: {//批量插入int on;printf("请输入想要插入的元素个数:\n");scanf("%d", &on);ElemType array[on];for (int i = 1; i <= on; i++) {getchar();printf("向循环链表第%d个位置插入元素为:", (i));scanf("%c", &array[i]);}for (int i = 1; i <= on; i++) {Status InsertStatus = ListInsert(list, i, array[i]);if (InsertStatus == OK) {printf("向循环链表第%d个位置插入元素%c成功!\n", i, array[i]);} else {printf("向循环链表第%d个位置插入元素%c失败!\n", i, array[i]);}}}break;case 9: {//输出链表元素//temp=0;//return 0;printf("现在链表的元素为:");printLinkList(list);}break;case 10: {//头插法创建单链表//getchar();LinkList L;printf("请输入五个字符:\n");CreateLinkList_H(L, 5);int length = GetLinkListLength(L);printf("\n循环链表的长度为:%d。 \n", length);printf("循环链表的元素为:");printLinkList(L);printf("\n");}break;case 11: {//尾插法创建单链表LinkList L;printf("请输入五个字符:\n");CreateLinkList_R(L, 5);int length = GetLinkListLength(L);printf("\n循环链表的长度为:%d。 \n", length);printf("循环链表的元素为:");printLinkList(L);printf("\n");}break;default:printf("输入错误,无此功能,请检查输入:\n\n");}}}
四、运行结果