得链表者得天下(中)
老样子,话不多说,就是锤。
设head指向单向非空链表,数据域值为正整数。
①求链表的中间结点。
②将两个升序链表合成一个升序链表。
③单链表的反转
④判断单链表是否有环
⑤取出有环链表中环的起始点
⑥取出有环链表中环的长度
开始锤:
1.
求链表的中间节点:
第一种方法,跑一边链表,统计一下几个节点,再跑到中间就完事。代码就不写了.
int length = 0; while(head) { head = head->next; length ++ ; }//这就是计算长度,在弄个一半就行
注意:要是奇数好办,偶数的话,要问清人家需要哪个,前半段还是后半段.
例:1 2 3 4 问人家要2 还是要4
另一个更灵巧的方法是,用两个指针,慢指针每次走一步,快指针每次走两步,当快指针走到链表的末端(NULL)时,慢指针正好指向了中间节点(大长腿跑呗)
代码如下:
ElemSN *findmidnode(ElemSN* h)
{
ElemSN* p,*q;
if(!h)//没接点返回空
return NULL;
for(q=h,p=h->next;p&&p->next;q=q->next,p=p->next->next);//查找的过程
return q;//q指向偶数的前半段
}
2.
将两个升序链表合成一个升序链表。
第一种方法,和合并升序数组一样指针上下跳就可以。
ElemSN * mergeascendlink(ElemSN *h1,ElemSN *h2)
{
if(!h1) return h2;
if(!h2) return h1;//h1空返回h2;h2空返回h1;
ElemSN *head,*p;
if(h1->data<h2->data)//确定head在哪里;
{
head=h1;
h1=h1->next;
}
else
{
head=h2;
h2=h2->next;
}
p=head;//放上P用来上下跳;
while(h1&&h2)//有一个完了就结束
{
if(h1->data>h2->data)
{
p->next=h2;//挂链
h2=h2->next;//后移
}
else
{
p->next=h1;
h1=h1->next;
}
p=p->next;//p后移
}
if(!h1) p->next=h2;//h1完了,挂上h2剩下的
else p->next=h1;//反之
return head;
}
第二种方法:
递归实现:
ElemSN * mergeascendlink(ElemSN *h1,ElemSN *h2)//这个递归呢需要大家那笔画一画在自己跑几遍就可以了。
{
if(h1==NULL) return h2;
if(h2==NULL) return h1;
ElemSN *head;
if(h1->data<h2->data)//比大小
{
h1->next = mergeascendlink(h1->next,h2);//挂链的过程,还是要自己多跑跑
head=h1;
}
else{
h2->next = mergeascendlink(h1,h2->next);
head=h2;
}
return head;
}
3.
单链表的反转,假设原链表为1->2->3,翻转以后的链表应该是1<-2<-3,即节点3变成了头节点。
看起来高大上,其实就是把链表分成第一个结点,和后面的结点,把后面的结点,头插就完事了。
代码如下:(顺便复习一下头插结点)
ElemSN * reversallink(ElemSN * h)
{
if(!h)
return NULL;//空链表返回NULL
ElemSN * p,*q;
p=h->next;
h->next=NULL;//断开
while(p)//头插
{
q=p;
p=p->next;
q->next=h;
h=q;
}
return h;
}
思考题:以组为单位翻转链表,组的长度用K表示,比如原链表为1->2->3->4->5,当K=2时,翻转的结果为2->1->4->3->5,当K=3时,翻转的结果为3->2->1->4->5,即先翻转K个,再翻转K个,当剩下的节点数小于K时,就不用翻转了。
可以试着做一下,下次有可能就给大家分享出来了。(关键有点长。。。)
4.
判断是否有环。做法也是用快慢指针,如果没有环,快指针一定先到达链表的末端(NULL),如果有环,快、慢指针一定会相遇在环中。(那么就是单循环双出口,出口一没环,出口二有环)
代码如下:
int judgering(ElemSN * h)
{
ElemSN * p,*q;
int flag=0;//先假设没有环
p=q=h;
while(q&&q->next)//从循环条件出来,一定没环(因为到了NULL)
{
p=p->next;
q=q->next->next;
if(p==q)
{
flag=1;
break;//break出来;有环,改一下flag的值
}
}
return flag;//flag=0没环;=1有环,主调判断下就完事了
}
5.
⑤取出有环链表中环的起始点
使用前后指针,(你先走,我再走)不是快慢指针,不是快慢指针,不是快慢指针,两个指针相遇的地方就是环的起始点。
代码如下:
ElemSN * detectEntry(ElemSN * head)
{
ElemSN *first,second;
//使用前后指针,此时fast每次也只移动一步
ElemSN *first = head , *second = head;
while(circleLen--) first = first->next; // first指针先出发
//然后两个指针同时向前走,每次走一步
while(first!=second){ first = first->next; second = second->next ; }
return first;
}
6.
⑥取出有环链表中环的长度
首先要找到环的起始点。指上一个指针,架设循环,弄一个累加器,没到起始点就加一;
代码如下:
int cnt = 1;ElemSN *temp = first->next;
while(temp!=first) { temp = temp->next; cnt ++; }
这里偷个懒,直接用了上面的first;就是简单的累加啦。大家不要在意。
最后附上总的代码:(我这里没环所以关于环的那几个,大家自己下去敲一下哦)
#include<stdio.h>
#include<stdlib.h>
#define N 6
typedef struct node{
int data;
struct node *next;
}ElemSN;
ElemSN *createlink1(int a[])
{
ElemSN *h=NULL,*tail,*p;
for(int i=0;i<N;i++)
{
p=(ElemSN*)malloc(sizeof(ElemSN));//分配一个动态单元给p
p->data=a[i];//数据域赋值
p->next=NULL;//指针域赋空
if(!h)
h=tail=p;//判断是不是第一个结点,是,头尾都指上来
else
tail=tail->next=p; //不是,挂链,挪尾指针。
}
return h;//返回头指针h
}
ElemSN *findmidnode(ElemSN* h)
{
ElemSN* p,*q;
if(!h)//没接点返回空
return NULL;
for(q=h,p=h->next;p&&p->next;q=q->next,p=p->next->next);//查找的过程
return q;//q指向偶数的前半段
}
ElemSN * mergeascendlink(ElemSN *h1,ElemSN *h2)//这个递归呢需要大家那笔画一画在自己跑几遍就可以了。
{
if(h1==NULL) return h2;
if(h2==NULL) return h1;
ElemSN *head;
if(h1->data<h2->data)//比大小
{
h1->next = mergeascendlink(h1->next,h2);//挂链的过程,还是要自己多跑跑
head=h1;
}
else{
h2->next = mergeascendlink(h1,h2->next);
head=h2;
}
return head;
}
/*ElemSN * mergeascendlink(ElemSN *h1,ElemSN *h2)//合并升序链(非递归)
{
if(!h1) return h2;
if(!h2) return h1;//h1空返回h2;h2空返回h1;
ElemSN *head,*p;
if(h1->data<h2->data)//确定head在哪里;
{
head=h1;
h1=h1->next;
}
else
{
head=h2;
h2=h2->next;
}
p=head;//放上P用来上下跳;
while(h1&&h2)//有一个完了就结束
{
if(h1->data>h2->data)
{
p->next=h2;//挂链
h2=h2->next;//后移
}
else
{
p->next=h1;
h1=h1->next;
}
p=p->next;//p后移
}
if(!h1) p->next=h2;//h1完了,挂上h2剩下的
else p->next=h1;//反之
return head;
}*/
ElemSN * reversallink(ElemSN * h)
{
if(!h)
return NULL;//空链表返回NULL
ElemSN * p,*q;
p=h->next;
h->next=NULL;//断开
while(p)//头插
{
q=p;
p=p->next;
q->next=h;
h=q;
}
return h;
}
void printlink(ElemSN*h)
{
ElemSN*p;
for(p=h;p;p=p->next)
printf("%5d",p->data);
printf("\n");
}
int main (void)
{
int a[N]={1,2,3,4,5,6};
ElemSN *head1=NULL,*head2=NULL,*head=NULL,*p,*q;
//正向创建链表
head1=createlink1(a);//用head1接收头指针
head2=createlink1(a);
//输出链表
printlink(head1);
p=findmidnode(head1);
printf("中间结点的值是:%d\n",p->data);
head=mergeascendlink(head1,head2);//合并
printlink(head);//输出一下合并后的
printf("\n");
q=reversallink(head); //反转链表
printlink(q);//输出反转后的
return 0;
}
我是小纸人,谢谢大家啦。
得链表者得天下(中)相关推荐
- java数组和链表的区别_java中链表和数组的区别?
综述:数组是线性结构,可以直接索引,即要去第i个元素,a[i]即可.链表也是线性结构,要取第i个元素,只需用指针往后遍历i次就可.貌似链表比数组还要麻烦些,而且效率低些. 想到这些相同处中的一些细微的 ...
- l2-004 这是二叉搜索树吗?_LeetCode 例题精讲 | 11 二叉树转化为链表:二叉树遍历中的相邻结点...
本期例题: LeetCode 98. Validate Binary Search Tree 验证二叉搜索树(Medium) LeetCode 426. Convert Binary Tree to ...
- 如下为利用Linux内核链表创建,Linux内核中链表的实现与应用
链表(循环双向链表)是Linux内核中最简单.最常用的一种数据结构. 1.链表的定义 struct list_head { struct list_head *next, *prev; } 这个不含数 ...
- python实现链表的删除_Python中 为我们提供了一些独特的解决方案的方法特性
实际上,在日常的工作中,我们很多需求,无论是常见的.还是不常见的,Python 都为我们提供了一些独特的解决方案,既不需要自己造轮子,也不需要引入新的依赖(引入新的依赖势必会增加项目的复杂度). 但是 ...
- 得链表者得天下(上)
直接开始干. 设head指向单向非空链表,数据域值为正整数. ①输出数据域的值. ②逆向输出数据域的值. ③返回所有结点的和. ④返回最小值. ⑤返回奇数结点的个数. ⑥返回数据域值为KEY的结点的地 ...
- java 将对象写入链表_在Java中,_____类可用于创建链表数据结构的对象。
摘要: 和翻杠杆转钢夹具既能夹紧矫正用于又能用于材,可用杠杆它是将工件夹紧的原理利用.限的钢板局部加热却后变形.建链据结冷的角是有,形约加热角变一次为(.平直将其压至时即可,表数工字钢时矫直用压弯曲力 ...
- 设A和B是两个单链表,其表中元素递增有序,使用一算法将A和B归并成一个案元素递减有序的单链表C
代码: LinkList* commonElem(LinkList* L1,LinkList* L2){LinkList* L = new LinkList;LinkList* rear = L;Li ...
- python单链表就地反转_Python中的就地字典反转
这不适用,但使用popitem()消耗oldDict from collections import defaultdict def invert(oldDict): invertedDict = d ...
- 数据结构 - 链表 - 面试中常见的链表算法题
数据结构 - 链表 - 面试中常见的链表算法题 数据结构是面试中必定考查的知识点,面试者需要掌握几种经典的数据结构:线性表(数组.链表).栈与队列.树(二叉树.二叉查找树.平衡二叉树.红黑树).图. ...
最新文章
- php结课答辩要求,毕业论文答辩的基本要求和评分标准
- 【 MATLAB 】使用 MATLAB 求某输入的稳态响应
- 网站怎样留住浏览用户
- 【Vegas原创】X connection to localhost:11.0 broken (explicit kill or server shutdown)解决方法...
- 浅谈工业机器人的运动停止
- grunt 插件_从Grunt测试Grunt插件
- c# 计算机ip,C# 获取电脑的IP,网关,MAC,计算机名。。
- [Leetcode]-- Valid Number
- 自动化测试unittest测试框架实例
- >>’ should be ‘> >’ within a nested template argument list
- python打开360浏览器_python 模拟浏览器访问网页 selenium+chromedriver+360浏览器
- android 请求https请求,Android 实现 HttpClient 请求Https
- Mac系统下Typora配置阿里云图床+上传工具PicGo安装
- 【Flutter】Dart 中国身份证验证,出生日期、性别、年龄查询
- 路遥《人生》中经典语录
- taskset 查询或设置进程绑定CPU(亲和性)
- 求字符串的全排列的递归实现(对字符串中有相同字符也适用)
- Python创建文件名为0000—nnnn的txt文件
- mysql-ACID
- 带孩子们做环球旅行的读后感_适合夏天制作的简单小手工,带着孩子们做起来!...
热门文章
- 高通正式发布骁龙 778G 5G 芯片
- 网友自制 MIUI 13 海报被疯传
- [翻译]在Windows版或MacOS版的Microsoft Edge上安装一个谷歌浏览器拓展
- 如何记账并生成收入、支出的图表
- 如何修理无线网络电视服务器,win7实现无线投屏到电视_网站服务器运行维护
- MySQL数据库——MySQL是什么?它有什么优势?
- Vue.js框架学习,数据绑定
- RK3568 外接 PCF8563 RTC
- GitLab允许开发人员推送到master分支
- python量化实战 顾比倒数线_龙腾四海:顾比倒数线+顾比均线