单链表插入元素 注释 c语言,数据结构之无头单链表的相关练习题——C语言实现(详细注释)...

本文中所用到的相关链表操作实现均在我上篇博客中:https://blog..net/haoziai905/article/details/87099287

1.删除无头单链表的非尾结点

这道题的重点就在于最后的非尾结点上,既然是非尾结点,则说明其下一个结点必定不为空。而我们通常所使用的删除节点的方法都需要知道所要删除节点的前一个结点,但是要找到链表中一个结点的前一个结点并容易,只能通过遍历链表去寻找,但是遍历链表的代价是非常大的。所以我们需要一个方法,让我们不需要遍历链表就能删除这个结点。

首先,我们需要明白删除一个结点的目的是什么。我们删除一个结点的目的是为了删除这个结点中所储存的数据,而不是一定要删除这个结点才行。所以我们可以通过交换要删除结点与下一个结点的数据,再将下一个结点删除就好了。而不需要去查找要删除结点的上一个结点。

//删除无头单链表的非尾结点

void DelNodeNotTail(pNode pos)

{

assert(pos);

assert(pos->next);

//交换pos结点与pos下一结点的元素

pNode cur = pos->next;

pos->data = cur->data;

pos->next = cur->next;

//删除pos结点的下一个结点

free(cur);

cur = NULL;

}

2.在无头单链表的一个位置前插入一个元素

这个题与上一个题类似,插入元素也是需要知道要插入位置的前一个结点才行,但是遍历链表的代价太大。所以我们也可以通过上一题交换结点中元素的方法来实现,在该位置后插入一个新结点,然后交换两个结点中的元素即可。

//在无头单链表的一个结点前插入一个结点

void InsertNode(pNode pos, DataType data)

{

assert(pos);

pNode cur = pos->next;//保存pos的下一结点位置

DataType tmp = pos->data;//保存pos结点的元素

//在pos位置后插入一个新结点,并交换pos结点与新结点的元素

pos->next = BuyNode(data);

pos->data = data;

pos->next->data = tmp;

//将链表重新连接起来

pos->next->next = cur;

}

3.约瑟夫环

约瑟夫环是什么呢?约瑟夫环(约瑟夫问题)是一个数学的应用问题:已知n个人(以编号1,2,3...n分别表示)围坐在一张圆桌周围。从编号为k的人开始报数,数到m的那个人出列;他的下一个人又从1开始报数,数到m的那个人又出列;依此规律重复下去,直到圆桌周围的人全部出列。我们需要通过代码来模拟约瑟夫环的过程,以此来知道谁会留到最后。

//约瑟夫环

void JosephusCycle(pList* pplist, int k)

{

pNode cur = *pplist;

pNode del = NULL;

//当cur==cur->next时说明只剩下一个人了

while (cur != cur->next)

{

for (int i = 1; i < k; i++)

{

cur = cur->next;

}

printf("The %d is die!\n", cur->data);

del = cur->next->next;//保存cur的下下一个结点

cur->data = cur->next->data;//交换cur结点和下一结点的元素

free(cur->next);//删除cur的下一结点

cur->next = del;//连接起链表

del = NULL;

}

*pplist = cur;

printf("The %d is live!\n", cur->data);

}

4.逆序单链表

要想将单链表逆序有两种方法,第一个方法就是通过三个指针实现,还有一种方法就是通过头插来实现。当我们将一个链表的结点从头到尾一个一个的头插到另一个新链表上时,这时新产生的链表就是第一条链表逆序后的样子。

//逆序链表:三指针法

void ReverseList(pList* pplist)

{

assert(pplist);

//当链表为空链表或者链表中只有一个元素时,不需要逆序

if ((*pplist) == NULL || (*pplist)->next == NULL)

{

return;

}

pNode frist = *pplist;

pNode second = frist->next;

pNode third = second->next;

while (second != NULL)

{

second->next = frist;

frist = second;

second = third;

if (third != NULL)

{

third = third->next;

}

}

(*pplist)->next = NULL;

*pplist = frist;

}

//逆序链表:头插法

void ReverseList(pList* pplist)

{

assert(pplist);

if ((*pplist) == NULL || ((*pplist)->next == NULL))

{

return;

}

pList pHead = NULL;

pNode cur = *pplist;

pNode tmp = cur->next;

while (cur)

{

//头插

if (pHead == NULL)

{

pHead = cur;

}

else

{

cur->next = pHead;

pHead = cur;

cur = tmp;

if (tmp)

{

tmp = tmp->next;

}

}

}

(*pplist)->next = NULL;

*pplist = pHead;

}

5.冒泡排序

冒泡排序时最简单的一种排序方法,实现起来也并不复杂,但是我们通常所实现的冒泡排序都是通过数组或者是顺序来实现的,那么在链表中我们应该如何实现冒泡排序呢?

//冒泡排序

void BubbleSort(pList plist)

{

if (NULL == plist)

{

return;

}

pNode tail = NULL;

while (tail != plist)

{

pNode cur = plist;

pNode next = cur->next;

int flag = 0;//设置标志位,提高排序效率

while (next != tail)

{

//升序排列

if (next->data < cur->data)

{

DataType tmp = next->data;

next->data = cur->data;

cur->data = tmp;

flag = 1;//如果单趟排序中发生了交换则将标志位置1

}

else

{

cur = next;

next = next->next;

}

}

//标志位为0则说明为发生元素交换,则剩下的元素已经有序,不需要排序,直接返回

if (flag == 0)

{

return;

}

tail = cur;

}

}

6.合并两个有序链表,合并后依然有序

只需要一一对比两个链表中元素的大小,然后按照我们所想要的顺序将大的元素或者小的元素尾插入新链表中即可。

//合并两个有序链表合并后仍然有序

pList Merge(pList plist1, pList plist2)

{

//1.两个链表是一条链表

//2.两条链表中有一条为空

//出现上面两种情况都不需要合并链表

if (plist1 == plist2)

{

return plist1;

}

if (plist1 == NULL)

{

return plist2;

}

if (plist2 == NULL)

{

return plist1;

}

pList newlist = NULL;

pList cur = NULL;

while (plist1 != NULL && plist2 != NULL)

{

//比较两条链表当前第一个结点元素的大小

//升序排列则将元素较小的结点接在新链表后

if (plist1->data < plist2->data)

{

if (newlist == NULL)

{

newlist = plist1;

cur = newlist;

}

else

{

cur->next = plist1;

cur = cur->next;

}

plist1 = plist1->next;

}

else

{

if (newlist == NULL)

{

newlist = plist2;

cur = newlist;

}

else

{

cur->next = plist2;

cur = cur->next;

}

plist2 = plist2->next;

}

}

//当其中一个链表已经为空时,直接将另一条链表的整条链表接在新链表后即可

if (plist1 == NULL && plist2 != NULL)

{

cur->next = plist2;

}

else if (plist1 != NULL && plist2 == NULL)

{

cur->next = plist1;

}

return newlist;

}

7.只遍历链表一遍,找到中间结点

//只遍历链表一遍,找到中间结点

pNode FindMidNode(pList plist)

{

//快慢指针法,快指针速度是慢指针速度的两倍

//当快指针走到链表尾时,则慢指针正好走到链表的中间位置

pNode fast = plist;

pNode slow = plist;

while (fast != NULL && fast->next != NULL)

{

slow = slow->next;

fast = fast->next->next;

}

return slow;

}

8.只遍历一遍找到链表的倒数第K个结点

//只遍历一遍找到链表的倒数第K个结点

pNode FindLastKNode(pList plist, int k)

{

if (plist == NULL)

{

return NULL;

}

int count = k;

pNode fast = plist;

pNode slow = plist;

//快指针先走K步

while (count--)

{

//如果快指针已经为空则说明链表中不足K个元素

if (fast == NULL)

{

return NULL;

}

fast = fast->next;

}

//快慢指针一起走,当快指针为空时,慢指针指的就是倒数第K个元素

while (fast != NULL)

{

fast = fast->next;

slow = slow->next;

}

return slow;

}

以上代码均通过VS2017环境测试。

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

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

相关文章

n个1组成的整数能被2013整除c语言,求大神解算法,“编写程序,求n至少为多大时,n个1组成的整数能被2013 整除。”...

编写程序&#xff0c;求n至少为多大时&#xff0c;n个1组成的整数能被2013 整除。使用python黑科技:i 1while int(1 * i) % 2013:i 1print(i)不使用黑科技:i s t 1while s % 2013:i 1t t * 10 % 2013s (s t) % 2013print(i)而事实上可以从数论的角度看。20133*11*61&a…

Java基础知识点复习

转载&#xff1a;https://mp.weixin.qq.com/s/M-6RSRcRd3X93cR7VXpanw Java概述 1.什么是Java&#xff1f; Java是一门面向对象的编程语言&#xff0c;不仅吸收了C语言的各种优点&#xff0c;还摒弃了C里难以理解的多继承、指针等概念&#xff0c;因此Java语言具有功能强大和…

c语言 求2到100的素数,2是素数吗(c语言输出100以内素数)

2是质数吗&#xff1f;除了1和本身外&#xff0c;不能被其他任何自然数整数的自然数。又叫做素数&#xff0c;最小的素数是2&#xff0c;也是唯一的偶质数 100以内的质数共有25个&#xff0c;这些质数我们经常用到&#xff0c;可以用下面的.1不是素数&#xff0c;最小的质数是2…

为什么都说Dubbo不适合传输大文件?Dubbo支持的协议

背景 之前公司有一个 Dubbo 服务&#xff0c;内部封装了腾讯云的对象存储服务 SDK&#xff0c;是为了统一管理这种三方服务的SDK&#xff0c;其他系统直接调用这个对象存储的 Dubbo 服务。用来避免因平台 SDK 出现不兼容的大版本更新&#xff0c;导致公司所有系统修改跟着升级…

中科院C语言应聘机试编程题6,中科院计算所保研笔试+机试+面试经验分享

计算所JDL(先进人机交互)实验室9月10号开始联系计算所导师&#xff0c;12号收到导师的回复&#xff0c;大致意思是老师让我提供三位本校推荐老师的联系方式&#xff0c;又问了是否有读博的打算&#xff0c;让我准备到计算所JDL面试&#xff0c;16号收到了他们的正式通知。老实说…

MySQL group_concat()详解

GROUP_CONCAT(xxx)&#xff1a;是将分组中括号里对应的字符串进行连接.如果分组中括号里的参数xxx有多行&#xff0c;那么就会将这多行的字符串连接&#xff0c;每个字符串之间会有特定的符号进行分隔。 对应的语法格式 # 将分组中column1这一列对应的多行的值按照column2 升序…

c语言编写劫持dll,c语言-----劫持自己02

在上一节 c语言-----劫持原理01 已经叙述了劫持原理&#xff0c;下边正式进入劫持实战1. 需要实现的功能在c语言中system("notepad") 可以打开一个记事本system("mspaint") 可以打开画图工具所以这次我们需要把 可以打开一个记事本 这个功能更改为 在控制…

Java中Runtime类

一、概述 Runtime类封装了运行时的环境。每个 Java 应用程序都有一个 Runtime 类实例&#xff0c;使应用程序能够与其运行的环境相连接。 一般不能实例化一个Runtime对象&#xff0c;应用程序也不能创建自己的 Runtime 类实例&#xff0c;但可以通过 getRuntime 方法获取当前R…

长春理工大学c语言实验题库,长春理工大学首届趣味心理知识竞赛初赛题库.doc...

长春理工大学首届趣味心理知识竞赛初赛题库长春理工大学首届趣味心理知识竞赛初赛题库心理知识简述1.心理学概念心理学是研究人的心理活动及其发生、发展规律的科学。人的心理是以不同的形式能动地反映客观事物及其相互关系的活动。人的心理活动包括有紧密联系的两个方面&#…

在Java中调用Python

写在前面 在微服务架构大行其道的今天&#xff0c;对于将程序进行嵌套调用的做法其实并不可取&#xff0c;甚至显得有些愚蠢。当然&#xff0c;之所以要面对这个问题&#xff0c;或许是因为一些历史原因&#xff0c;或者仅仅是为了简单。恰好我在项目中就遇到了这个问题&#…

android 导航动画,安利一个Android导航库

SlidingRootNav这是一个像DrawerLayout一样的抽屉式的导航库&#xff0c;这个库实现的抽屉在content view的下层&#xff0c;滑动之后&#xff0c;才能看到相应的导航页使用Gradle添加依赖compile com.yarolegovich:sliding-root-nav:1.0.2使用说明创建一个 content_view.xml或…

将String集合转为Integer集合的三种方法

第一种方法&#xff1a; List<String> list Arrays.asList("1", "2", "3", "4", "5");// method1 创建一个Integer类型的集合&#xff0c;循环遍历String类型的数组并把数据添加进集合List<Integer> integerLi…

android 界面组件,安卓开发学习周第三篇——Android中的UI组件

原标题&#xff1a;安卓开发学习周第三篇——Android中的UI组件在Android APP中&#xff0c;所有的用户界面元素都是由View和ViewGroup的对象构成的。View是绘制在屏幕上的用户能与之交互的一个对象。而ViewGroup则是一个用于存放其他View(和ViewGroup)对象的布局容器&#xff…

Spring Boot集成Druid出现异常报错的原因及解决

Druid 可以很好的监控 DB 池连接和 SQL 的执行情况&#xff0c;天生就是针对监控而生的 DB 连接池。本文讲述了Spring Boot集成Druid项目中discard long time none received connection异常的解决方法&#xff0c;出现此问题的同学可以参考下 文章目录Spring Boot集成Druid异常…

BigDecimal.ZERO替代new BigDecimal(0)

这里只是想分享下&#xff0c;平时如果我们想要定义一些BigDecimal类型的变量&#xff0c;可以先看看BigDecimal有没有已经先做了定义&#xff0c;如new BigDecimal(0)就可以用BigDecimal.ZERO来代替&#xff0c;如下&#xff1a; BigDecimal bigDecimal BigDecimal.ZERO;描述…

用js拼html写下拉框,js实现下拉框效果(select)

效果图&#xff1a;代码如下&#xff1a;*{padding: 0;margin:0;}ul,li{list-style: none}.left{float: left;}.right{float: right;}.select_contain{font-size: 14px;color: #333;line-height: 38px;margin: 30px 0;}.select_item{margin-right: 50px;position: relative;}.s…

Gson Builder — 基础 命名策略

文章目录Gson Builder — 基础& 命名策略GsonBuilder 基础命名策略字段命名策略 - IDENTITY字段命名策略 - LOWER_CASE_WITH_UNDERSCORES字段命名策略 - LOWER_CASE_WITH_DASHES字段命名策略 - UPPER_CAMEL_CASE字段命名策略 - UPPER_CAMEL_CASE_WITH_SPACESSerializedName…

keil html转换工具,网页转换工具FCARM和makefsfile的使用简介

网页转换工具FCARM和makefsfile的使用简介[复制链接]首先在这里要提一下Keil的网页转换工具FCARM.exe的使用&#xff0c;花费了我好几个小时。TI也有一个类似的程序&#xff0c;是Makefsfile&#xff0c;并且源码公开的。1.gif (31.45 KB, 下载次数: 0)2010-11-8 16:44 上传2.j…

Google Gson用法详解

文章目录一、简介二、依赖三、基本用法1、创建Gson实例1.1、new Gson()1.2、GsonBuilder.build()2、Java对象–>JSON3、JSON–>Java对象4、漂亮地输出5、JSON array --> Java array/list5.1 、 JSON array -->Java对象5.2 、JSON array–>List5.3 、JSON array–…

android lua loadluafile 相对路径,Lua中的loadfile、dofile、require详解

1.loadfile——只编译&#xff0c;不运行javaloadfile故名思议&#xff0c;它只会加载文件&#xff0c;编译代码&#xff0c;不会运行文件里的代码。好比&#xff0c;咱们有一个hellofile.lua文件&#xff1a;函数复制代码代码以下:print(“hello”);function hehe()print(“he…