单向循环链表的简单实现

xiaoxiao2021-02-28  115

单向循环链表:       在单向链表中,头指针是相当重要的,因为单向链表的操作都需要头指针,所以如果头指针丢失或者破坏,那么整个链表都会遗失,并且浪费链表内存空间。 单向循环链表的构成:       如果把单链表的最后一个节点的指针指向链表头部,而不是指向NULL,那么就构成了一个单向循环链表。 单向链表结构图示:(以下示意图均摘自 来源:  http://blog.csdn.net/fisherwan/ar 单向循环链表的初始化: 当单向循环链表中只有一个节点时,那么这个节点的next指针指向的就是这个节点本身。 单向循环链表的创建:           单向循环链表的创建和单向链表很相似,不同的地方是新插入节点的next指向的不再是NULL,而是指向第一个节点。 代码如下: 遍历到链表的最后一个节点ptemp; ptemp->next = pnew; pnew->next = head; 单向循环链表的插入: 单向循环链表的插入与单向链表有所不同,因为单向循环链表首尾相连,所以没有从尾部插入的问题。 (1)从链表头部插入 将新插入的节点变为链表头部,next指向原来的第一个节点,在遍历整个链表找到链表末尾(即它的next指向的是head的那个节点),将这个节点的next指向新插入的节点,最后再将链表头指针指向新节点。 代码如下: pnew->next = head->next; ptemp = head; while(ptemp->next != head)       //注意此时的遍历条件是 ptemp->next != head          ptemp = ptemp->next;     //退出while循环后ptemp指向链表尾部 ptemp->next = pnew; head = pnew; (2)从链表中间插入 此时插入的过程和单向链表的一样,找到要插入位置前驱节点ptemp,将新插入节点的next指向ptemp的next,再将ptemp的next指向新插入的节点pnew。 代码如下: pnew->next = ptemp->next; ptemp->next  = pnew; 以上的顺序不能变 单向循环链表的删除: 删除操作与插入操作类似,也分为两种情况: (1)在链表头部删除 将链表头指针指向第二个节点,再将最后一个节点的指针指向新插入的节点,最后释放掉原来第一个节点的内存空间 代码如下: ptemp = head; first = head; while(ptemp->next != head)     ptemp = ptemp->next;   //退出while循环后ptemp指向链表尾部 head= head->next;//头指针指向第二个节点 ptemp->next = headt;//指向第二个节点 free(first);//释放掉原来的第一个节点 (2)在链表中间删除 找到要删除的链表的前驱节点ptr,将ptr的next指向pdelete的next,再释放掉pdelete的内存空间。 代码如下: ptr = head; while(ptr->next != del)     ptr = ptr->next;//退出循环后此时ptr为pdelete的前驱 pdelete = ptr->next; ptr-next = pdelete->next; 单向循环链表的C语言实现:(codeblocks完美运行) #include <stdlib.h> #include <stdio.h> typedef struct circle_list { int date; struct circle_list *next; }list; //节点创建函数 list *creat_node() { //创建头节点 list *newnode = (list *)malloc(sizeof(struct circle_list)); if(newnode == NULL) { printf("创建头结点失败!\n"); } else { newnode->next=NULL; return newnode; } } //插入数据到链表中 int insert_list(list *head) { //创建节点 int val; printf("请输入要插入的元素:"); scanf("%d",&val); list *newnode = creat_node(); newnode->date = val; //判断头节点是否为NULL if(head != NULL) { //遍历头节点,中间变量P list *p = head; //遍历头节点到,最后一个数据 while(p->next != head ) { //错误,这样会改变头节的位置,必须使用中间变量进行变量 // head = head->next; p = p->next; } //把最后一个节点赋新的节点过去 p->next = newnode; newnode->next = head; return 1; } else { printf("head is NULL\n"); return 0; } } //遍历链表中的数据 int display(list *head) { if(head != NULL) { //遍历头节点,中间变量P list *p = head; //遍历头节点到,最后一个数据 while(p->next != head ) { //错误,这样会改变头节的位置,必须使用中间变量进行变量 // head = head->next; printf("%d ",p->next->date); p = p->next; } //把最后一个节点赋新的节点过去 return 1; } else { printf("头结点为空!\n"); return 0; } } int delete_list(list *head) { if(head == NULL) { printf("链表为空!\n"); return 0; } list *temp = head; list *ptr = head->next; int del; printf("请输入你要删除的元素:"); scanf("%d",&del); while(ptr != head) { if(ptr->date == del) { if(ptr->next == head)//循环结束的条件换成ptr->next == head { temp->next = head; free(ptr); return 1; } temp->next = ptr->next; free(ptr); //printf("元素删除成功!\n"); return 1; } temp = temp->next; ptr = ptr->next; } printf("没有找到要删除的元素%d\n",del); return 0; } int update_list(list *head) { if(head == NULL) { printf("链表为空!\n"); return 0; } list *temp = head; int olddate,newdate; printf("请输入要修改的元素:"); scanf("%d",&olddate); printf("修改为:"); scanf("%d",&newdate); while(temp->next != head) { if(temp->next->date == olddate) { temp->next->date = newdate; return 1; } temp = temp->next; } printf("没有找到要修改的元素!\n"); return 0; } int seek_list(list*head) { if(head == NULL) { printf("链表为空!\n"); return 0; } int val,i=0; printf("请输入要查找的元素:"); scanf("%d",&val); list *p = head; while(p->next != head) { i++; if(p->next->date == val) { printf("找到元素%d,位置在%d\n",val,i); } p = p->next; } printf("没有找到该元素!\n"); return 0; } void menu() { system("cls");//清屏 printf("\t\t|===============================================|\t\t\n"); printf("\t\t|==================单向循环操作=================|\t\t\n"); printf("\t\t|===================1.插入元素==================|\t\t\n"); printf("\t\t|===================2.打印链表==================|\t\t\n"); printf("\t\t|===================3.删除元素==================|\t\t\n"); printf("\t\t|===================4.修改链表==================|\t\t\n"); printf("\t\t|===================5.查找元素==================|\t\t\n"); printf("\t\t|==请输入对应的数字执行对应的功能!(输入0退出)==|\t\t\n"); printf("\t\t|====== 作者:RXX 时间:2017/07/06 ======|\t\t\n"); printf("\t\t|===============================================|\t\t\n"); } int main() { //创建头节点 list *head = creat_node(); //让头字节自我循环 head->next = head; int num; menu(); scanf("%d",&num); //插入节点 while(num) { switch(num) { case 1: { printf("插入元素操作:\n"); if(insert_list(head)) printf("插入节点成功!\n"); else printf("插入节点失败!\n"); break; } case 2: { printf("打印链表操作:\n"); display(head); break; } case 3: { if(delete_list(head)) printf("删除节点成功!\n"); break; } case 4: { if(update_list(head)) printf("修改元素成功!\n"); break; } case 5: { if(seek_list(head)) printf("查找元素成功!\n"); break; } } getch(); menu(); scanf("%d",&num); //清空缓存区 //while(getchar()!='\n'); } printf("\t\t|================感谢使用!再见!===============|\t\t\n"); return 0; } 运行界面:
转载请注明原文地址: https://www.6miu.com/read-38089.html

最新回复(0)