单向循环链表的简单实现
来源:互联网 发布:windows10 配置mysql 编辑:程序博客网 时间:2024/05/17 05:57
单向循环链表:
在单向链表中,头指针是相当重要的,因为单向链表的操作都需要头指针,所以如果头指针丢失或者破坏,那么整个链表都会遗失,并且浪费链表内存空间。
单向循环链表的构成:
如果把单链表的最后一个节点的指针指向链表头部,而不是指向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;}
阅读全文
0 0
- 单向循环链表的简单实现
- 单向循环链表的C++实现
- 单向循环链表的实现
- 单向循环链表的简单实现--数据结构学习(二)
- [Java]单向链表 ,循环链表的简单使用方法
- Python 实现简单的单向链表
- 单向链表的java简单实现
- 单向链表的简单实现
- 单向链表的简单实现
- 单向循环链表简单应用
- 约瑟夫问题的单向循环链表的代码实现
- 使用C++实现的单向循环链表
- 单向循环链表的实现C++封装
- c语言:单向循环链表的实现
- 循环链表的C风格实现(单向)
- 单向链表简单实现
- 简单单向链表实现
- 单向链表简单实现
- NP完全问题 8.12
- spring boot security mybitis
- 堆内存过大 Grow heap (frag case) to 39.580MB for 2560016-byte allocation
- 通过rsync+inotify实现多服务器文件的实时同步
- 丰富的应用图标库--阿里矢量图库
- 单向循环链表的简单实现
- caffe训练自己的数据集
- 【Linux】TCP 三次握手与四次挥手
- 解决沉浸式状态栏输入法弹起把状态栏顶上去的问题
- VLC优化(1) avformat_find_stream_info接口延迟降低——已知流信息
- 2017西安交大ACM小学期 文本查找[AC自动机]
- 循环链表与双向链表
- 628. Maximum Product of Three Numbers
- [bzoj1098][POI2007]办公楼biu