老样子,话不多说,就是锤。

设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; 
}

我是小纸人,谢谢大家啦。

得链表者得天下(中)相关推荐

  1. java数组和链表的区别_java中链表和数组的区别?

    综述:数组是线性结构,可以直接索引,即要去第i个元素,a[i]即可.链表也是线性结构,要取第i个元素,只需用指针往后遍历i次就可.貌似链表比数组还要麻烦些,而且效率低些. 想到这些相同处中的一些细微的 ...

  2. l2-004 这是二叉搜索树吗?_LeetCode 例题精讲 | 11 二叉树转化为链表:二叉树遍历中的相邻结点...

    本期例题: LeetCode 98. Validate Binary Search Tree 验证二叉搜索树(Medium) LeetCode 426. Convert Binary Tree to ...

  3. 如下为利用Linux内核链表创建,Linux内核中链表的实现与应用

    链表(循环双向链表)是Linux内核中最简单.最常用的一种数据结构. 1.链表的定义 struct list_head { struct list_head *next, *prev; } 这个不含数 ...

  4. python实现链表的删除_Python中 为我们提供了一些独特的解决方案的方法特性

    实际上,在日常的工作中,我们很多需求,无论是常见的.还是不常见的,Python 都为我们提供了一些独特的解决方案,既不需要自己造轮子,也不需要引入新的依赖(引入新的依赖势必会增加项目的复杂度). 但是 ...

  5. 得链表者得天下(上)

    直接开始干. 设head指向单向非空链表,数据域值为正整数. ①输出数据域的值. ②逆向输出数据域的值. ③返回所有结点的和. ④返回最小值. ⑤返回奇数结点的个数. ⑥返回数据域值为KEY的结点的地 ...

  6. java 将对象写入链表_在Java中,_____类可用于创建链表数据结构的对象。

    摘要: 和翻杠杆转钢夹具既能夹紧矫正用于又能用于材,可用杠杆它是将工件夹紧的原理利用.限的钢板局部加热却后变形.建链据结冷的角是有,形约加热角变一次为(.平直将其压至时即可,表数工字钢时矫直用压弯曲力 ...

  7. 设A和B是两个单链表,其表中元素递增有序,使用一算法将A和B归并成一个案元素递减有序的单链表C

    代码: LinkList* commonElem(LinkList* L1,LinkList* L2){LinkList* L = new LinkList;LinkList* rear = L;Li ...

  8. python单链表就地反转_Python中的就地字典反转

    这不适用,但使用popitem()消耗oldDict from collections import defaultdict def invert(oldDict): invertedDict = d ...

  9. 数据结构 - 链表 - 面试中常见的链表算法题

    数据结构 - 链表 - 面试中常见的链表算法题 数据结构是面试中必定考查的知识点,面试者需要掌握几种经典的数据结构:线性表(数组.链表).栈与队列.树(二叉树.二叉查找树.平衡二叉树.红黑树).图. ...

最新文章

  1. php结课答辩要求,毕业论文答辩的基本要求和评分标准
  2. 【 MATLAB 】使用 MATLAB 求某输入的稳态响应
  3. 网站怎样留住浏览用户
  4. 【Vegas原创】X connection to localhost:11.0 broken (explicit kill or server shutdown)解决方法...
  5. 浅谈工业机器人的运动停止
  6. grunt 插件_从Grunt测试Grunt插件
  7. c# 计算机ip,C# 获取电脑的IP,网关,MAC,计算机名。。
  8. [Leetcode]-- Valid Number
  9. 自动化测试unittest测试框架实例
  10. >>’ should be ‘> >’ within a nested template argument list
  11. python打开360浏览器_python 模拟浏览器访问网页 selenium+chromedriver+360浏览器
  12. android 请求https请求,Android 实现 HttpClient 请求Https
  13. Mac系统下Typora配置阿里云图床+上传工具PicGo安装
  14. 【Flutter】Dart 中国身份证验证,出生日期、性别、年龄查询
  15. 路遥《人生》中经典语录
  16. taskset 查询或设置进程绑定CPU(亲和性)
  17. 求字符串的全排列的递归实现(对字符串中有相同字符也适用)
  18. Python创建文件名为0000—nnnn的txt文件
  19. mysql-ACID
  20. 带孩子们做环球旅行的读后感_适合夏天制作的简单小手工,带着孩子们做起来!...

热门文章

  1. 高通正式发布骁龙 778G 5G 芯片
  2. 网友自制 MIUI 13 海报被疯传
  3. [翻译]在Windows版或MacOS版的Microsoft Edge上安装一个谷歌浏览器拓展
  4. 如何记账并生成收入、支出的图表
  5. 如何修理无线网络电视服务器,win7实现无线投屏到电视_网站服务器运行维护
  6. MySQL数据库——MySQL是什么?它有什么优势?
  7. Vue.js框架学习,数据绑定
  8. RK3568 外接 PCF8563 RTC
  9. GitLab允许开发人员推送到master分支
  10. python量化实战 顾比倒数线_龙腾四海:顾比倒数线+顾比均线