4、循环单链表

news/2024/9/20 5:13:10/文章来源:https://www.cnblogs.com/xpp3/p/18413303

1、代码实现

#include<stdio.h>
#include<malloc.h>
#include<assert.h>
typedef int ElemType;typedef struct Node{ElemType data;struct Node* next;
}Node,*PNode;typedef struct SCList{PNode first;PNode last;int size;
}SCList;void initSCList(SCList* list){//申请空间 创建虚拟头节点 Node* node = (Node*)malloc(sizeof(Node));assert(node != NULL);//第一个节点 和 最后一个节点 指向虚拟头节点 list->first = list->last = node;//虚拟头结点指向自己完成循环 node->next = node;//当前链表大小为0 list->size = 0;
}//申请节点 
Node* malloc_node(ElemType e){Node* node = (Node* )malloc(sizeof(Node));assert(node != NULL);node->next = NULL;node->data = e;return node;
}//尾插 
void push_back(SCList* list,ElemType e){//申请新节点 Node* node = malloc_node(e);//链表最后一个节点指向新节点 list->last->next = node;//更新last指针 list->last = node;//新节点的next指向第一个节点 形成循环 node->next = list->first;//元素数量+1 list->size++;
}//头插 
void push_front(SCList* list,ElemType e){//申请新节点 Node* node = malloc_node(e);node->next = list->first->next;list->first->next = node;//判断当前链表是否为空 if(list->first == list->last){//为空当前插入的节点则为last所指向的节点 list->last = node;}list->size++;
}
//打印链表
void show_SCList(SCList* list){Node* p = list->first->next;while(p != list->first){printf("%d->",p->data);p = p->next;}printf("NULL .\n last=%d,size=%d",list->last->data,list->size);
} //删除尾部 
void pop_back(SCList* list){if(list->size == 0){//当前链表为空printf("当前链表为空,不可删除.\n");return; }    PNode p = list->first;while(p->next != list->last){p = p->next;}free(list->last);list->last = p;p->next = list->first;list->size--;
}//删除头部
void pop_front(SCList* list){if(list->size == 0){//当前链表为空printf("当前链表为空,不可删除.\n");return; }Node* node = list->first->next;list->first->next = node->next;if(list->size == 1){//说明删除的是最后一个元素list->last = list->first; }free(node);list->size--;
} //插入元素 [默认链表升序排序] 
void insert_val(SCList* list,ElemType e){Node* node = malloc_node(e);Node* p = list->first;while(p->next != list->first && p->next->data < e){p = p->next;} node->next = p->next;p->next = node;if(node->next == list->first){//说明插入的位置是末尾list->last = node; }list->size++;
}//查找元素
Node* find(SCList* list,ElemType key){if(list->first == list->last){return NULL;} Node* p = list->first->next;while(p != list->first){if(p->data == key){return p;}p = p->next;}return NULL;
} //返回链表长度
int length(SCList list){return list.size;
}//按值删除
void delete_val(SCList* list,ElemType e){if(list->size == 0){return;}Node* p = find(list,e);if(p == NULL){return;}if(p->next == list->last){pop_back(list);}else{p->data = p->next->data;p->next = p->next->next; free(p);list->size--;}
} //排序
void sort(SCList* list){if(list->size <= 1){return;}//指向第一个节点 Node* p = list->first->next;//指向第二个节点 Node* q = p->next;//将原链表最后一个节点指向NULL list->last->next = NULL;//改变last指针指向第一个节点 list->last = p;//形成循环p->next = list->first; while(q != NULL){p = q;q = q->next;Node* s = list->first; //找到要插入的位置的上一个节点 while(s->next != list->first && s->next->data < p->data){s = s->next;} //插入该节点p->next = s->next;s->next = p;if(s->next == list->first){//插入的位置是末尾list->last = p;}}
} //逆置链表
void reverse(SCList* list){if(list->size <= 1){return;}//指向第一个节点 Node* p = list->first->next;//指向第二个节点 Node* q = p->next;//将原链表最后一个节点指向NULL list->last->next = NULL;//改变last指针指向第一个节点 list->last = p;//形成循环list->last->next = list->first;while(q != NULL){p = q;q = q->next;//头插法插入节点 p->next = list->first->next;list->first->next = p;} 
} //清空链表 
void clear(SCList* list){Node* p = list->first->next;while(p != list->first){list->first->next = p->next;free(p);p = list->first->next;}list->last = list->first->next = list->first;list->size = 0;
} //销毁链表
void destroy(SCList* list){clear(list);free(list->first);list->first = list->last = NULL;
} 
int main(){SCList list;initSCList(&list);int select = 1;ElemType item = 0;while(select){printf("\n");printf("***********************************\n");printf("* [1] push_back   [2] push_front  *\n");        printf("* [3] show_list   [4] pop_back    *\n");printf("* [5] pop_front   [6] insert_val  *\n");printf("* [7] find        [8] length      *\n");printf("* [9] delete_val  [10] sort       *\n");printf("* [11] reverse    [12] clear      *\n");printf("* [13] destroy    [0] exit_system *\n");printf("***********************************\n");printf("请选择> ");scanf("%d",&select);if(!select){break;}PNode p = NULL;switch(select){case 1:printf("请输入要输入的数据(-1结束):>");while(scanf("%d",&item),item != -1){push_back(&list,item);}break;case 2:printf("请输入要输入的数据(-1结束):>");while(scanf("%d",&item),item != -1){push_front(&list,item);}break;case 3:show_SCList(&list);break;case 4:pop_back(&list);break;case 5:pop_front(&list);break;case 6:printf("请输入要插入的数据:>");scanf("%d",&item);insert_val(&list,item);break;case 7:printf("请输入要查找的数据:>");scanf("%d",&item);p = find(&list,item);if(p == NULL){printf("查找的数据不存在.\n");}break;case 8:printf("该链表长度为: %d.\n",length(list));break;case 9:printf("请输入要删除的数据:>");scanf("%d",&item);delete_val(&list,item);break;    case 10:sort(&list);break;case 11:reverse(&list);break;case 12:clear(&list);break;case 13:destroy(&list);break; }    }destroy(&list);return 0;
} 

2、排序和逆置代码画图演示

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/796878.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

论文分享 《Timing Side-channel Attacks and Countermeasures in CPU Microarchitectures》

Attack 概述 传统攻击(CONVENTIONAL ATTACKS) 在传统攻击中,Attacker 通常:与 Victim 共享硬件资源 (比如说 LLC,BP,Prefetcher 等) 可以观察,改变微架构状态攻击步骤本文作者将传统攻击分为以下三步,如 Fig 1 所示:定位“漏洞”:该漏洞包括“代码漏洞”(vulnerab…

PbootCMS访问页面出现PHP Fatal error: Allowed memory size of 13421

当访问 PbootCMS 页面时出现 PHP Fatal error: Allowed memory size of 13421 的错误,通常是由于 PHP 的内存限制过低导致的。这个错误表明 PHP 脚本在运行过程中耗尽了分配给它的内存。 解决方案增加 PHP 内存限制 检查 PHP 配置文件 (php.ini) 在脚本中动态增加内存限制详细…

什么是 PHP? 为什么用 PHP? 有谁在用 PHP?

PHP,全称“PHP: Hypertext Preprocessor”,是一种开源的服务器端脚本语言,主要用于网页开发,能够产生动态交互性数据。它由Rasmus Lerdorf在1994年创建,并随着时间的推移不断更新迭代,以适应互联网技术的发展。为什么使用 PHP? 开源免费:PHP作为一个开源项目,用户可以…

系统配置nginx环境运行pbootcms访问首页直接404的问题

在安装 PbootCMS 时遇到访问首页返回 404 错误的问题,尤其是在 Windows + Nginx + PHP 的环境下,可能涉及到多个方面的配置问题。根据你的描述,填写授权码后问题得以解决。以下是详细的分析和解决方案,希望能帮助遇到类似问题的朋友。 问题分析与解决方案 1. 配置 Nginx 伪…

基于Java+Springboot+Vue开发的在线摄影预约管理系统

项目简介该项目是基于Java+Springboot+Vue开发的在线摄影预约管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的在线摄影管理系统项目,大学生可以在实践…

【痛点解决】跨网跨区域的文件传输摆渡解决办法指南

跨网跨区域的文件传输摆渡,顾名思义就是需要跨越不同网络、不同地区,或者是不同安全域的文件传输,一般有这样传输需求的机构,在组织架构、网络结构,或者传输需求上,都会比较复杂。 跨网跨区域文件传输是什么样的场景? 跨网跨区域文件传输涉及在不同的网络和地理区域之间…

SQL Server 中的 NUL 设备/NIL设备

SQL Server 中的 NUL 设备/NIL设备 在 SQL Server 中,有一个特殊的设备叫做 NUL(注意,不是 NULL),它类似于文件系统中的“黑洞”。NUL 设备类似于 Linux 系统中的 /dev/null,所有写入到 NUL 的数据都会被直接丢弃。 我们可以利用这个特性,在不需要实际生成备份文件的情况…

PbootCMS调用内容中换行符br不换行怎么办

在 PbootCMS 中,如果你在后台输入的文字包含换行符(如 <br>),但在前台显示时这些换行符被直接输出为文本(如 <br>),可以通过解码标签来解决这个问题。 解决方案 在需要输出的标签中加入 decode=1 参数,这样可以将 HTML 特殊字符解码为实际的 HTML 标签,从…

PbootCMS提交留言成功后跳转到指定的网址

要实现在 PbootCMS 中留言表单提交成功后跳转到指定网址,可以通过修改相关文件来实现。以下是详细的步骤: 步骤 1:定位相关文件 首先找到包含留言表单提交逻辑的相关文件。通常情况下,留言表单的提交逻辑会在 /core/function/helper.php 文件中。 步骤 2:修改提交成功后的…

PbootCMS判断一个字段为空的时候调用另外一个字段

在 PbootCMS 中,如果你想在一个字段为空时调用另一个字段,可以使用条件判断标签来实现。下面是一个具体的示例,展示了如何在某个字段为空时调用另一个字段。 示例场景 假设你有一个字段 ext_icos 用于存储图片,还有一个字段 ico 作为备用的缩略图。当 ext_icos 字段不为空时…

人员睡岗检测识别系统

人员睡岗检测识别系统是基于现场监控摄像头视频采集现场的监控图像画面,人员睡岗检测识别系统运用ai智能神经网络算法和机器学习技术,替代人的眼睛,全天候不间断监控人员办公区域,自动对视频监控画面人员睡岗离岗行为进行分析识别,为安全工作护航。该系统应用已有的监控摄…

PbootCMS生成的sitemap.xml中增加tag标签链接

打开/apps/home/model/SitemapModel.php,在78行后面增加个指定分类标签调用代码 // 指定分类标签调用 public function getSortTags($scode) {$join = array(array(ay_content_sort b,a.scode=b.scode,LEFT),array(ay_model c,b.mcode=c.mcode,LEFT));$scode_arr = array();if…