四道有趣的单链表面试题

数据结构与算法学习笔记(三)单向链表 一. 几个概念 0x01 链表   链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针连接次序实现的。链表是以结点的方式存储的,是链式存储。结点可以在运行时动态生成。链表是有序的列表,但其在内存中的存储是非连续、非顺序的。 0x02 结点   在链表数据结构中,我们把一个数据元素的存储映像称为结点(Node)。而一个结点包含存储数据元素的两部分信息:数据域(Data)和指针域(Next)。 0x03 数据域、指针域 数据域:存储数据元素信息的域; 指针域:存储直接后继位置 阅读详情

四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)

以下给出链表结点的数据结构:

template <class T>
struct LinkNode{   //链表节点
T data;
LinkNode<T>* link;
LinkNode(LinkNode<T>* ptr=NULL){link=ptr;}
LinkNode(const T& x,LinkNode<T>* ptr=NULL){link=ptr;data=x;}
};

以下给出链表的定义(带有附加头结点):

template <class T>
class SList{
private:
LinkNode<T>* first;
public:
SList(){first=new LinkNode<T>;}   //构造函数
SList(T& x){first=new LinkNode<T>(x);} //构造函数
SList(SList<T>& L); //复制构造函数
~SList();  //析构函数
int Length()const; //链表长度
LinkNode<T>* getHead()const{return first;}
void setHead(LinkNode<T>* p){first=p;}
bool Search(T& x);//搜索x元素
LinkNode<T>* Locate(int i)const; //定位
T getData(int i)const;   //取出元素值
void setData(int i,const T& x); //设置元素值
bool Insert(int i,const T& x); //插入
bool Remove(int i); //删除第i个元素
bool isEmpty()const{return first->link==NULL?true:false;}
bool isFull()const{return false;}
void Input(int endTag);
void vInput(int endTag);
void Output()const;
void Reverse();
LinkNode<T>* findMid();
SList<T>& operator=(SList<T>& L);
};

Q1 单链表的反序(cur为链表的第一个元素,next为cur的下一个元素,每次将next移到first后面之后,cur是一直不变的,next移动成功之后,重新设置next=cur->link)

(我将题目的意思理解错了,下面的程序实在头结点不变的情况下,对单链表进行反转,但是实际上应该是头结点变成尾节点,尾节点变成头结点,哎呀,懒得改了)

template <class T>
void SList<T>::Reverse(){
if(first->link==NULL||first->link->link==NULL) {cout<<"不需要倒置"<<endl;return;};
LinkNode<T>* cur=first->link;
LinkNode<T>* next=cur->link;
while(cur->link!=NULL){
cur->link =next->link;
next->link=first->link;
first->link=next;
next=cur->link;
}
}

Q2 找出链表的中间元素

思路分析:
 单链表的一个比较大的特点用一句广告语来说就是“不走回头路”,不能实现随机存取(random access)。如果我们想要找一个数组a的中间元素,直接a[len/2]就可以了,但是链表不行,因为只有a[len/2 - 1] 知道a[len/2]在哪儿,其他人不知道。因此,如果按照数组的做法依样画葫芦,要找到链表的中点,我们需要做两步(1)知道链表有多长(2)从头结点开始顺序遍历到链表长度的一半的位置。这就需要1.5n(n为链表的长度)的时间复杂度了。有没有更好的办法呢?有的。想法很简单:两个人赛跑,如果A的速度是B的两倍的话,当A到终点的时候,B应该刚到中点。这只需要遍历一遍链表就行了,还不用计算链表的长度。

template <class T>
LinkNode<T>* SList<T>::findMid(){
if(first->link==NULL) return first;
LinkNode<T>* slow=first;
LinkNode<T>* fast=first;
while(fast!=NULL&&fast->link!=NULL){
slow=slow->link;
fast=fast->link->link;}
return slow;
}

(上面的程序,如果链表的长度为奇数,显然找到中间元素,如果链表的长度为偶数,找的是中间两个元素之中的第二个元素)

Q3  链表排序(没看懂to be continued)

Q4  判断一个单链表是否有环

思路分析:
   这道题是《C专家编程》中的题了。其实算法也有很多,比如说:我觉得进行对访问过的结点进行标记这个想法也不错,而且在树遍历等场合我们也经常使用。但是在不允许做标记的场合就无法使用了。在种种限制的条件下,就有了上面的这种算法,其实思想很简单:就像两个人在操场上跑步一样,只要有个人的速度比另一个人的速度快一点,他们肯定会有相遇的时候的。不过带环链表与操场又不一样,带环链表的状态是离散的,所以选择走得快的要比走得慢的快多少很重要。比如说这里,如果一个指针一次走三步,一个指针一次走一步的话,很有可能它们虽然在一个环中但是永远遇不到,这要取决于环的大小以及两个指针初始位置相差多少了。

template <class T>
bool isLoop(SList<T>& L){
LinkNode<T>* slow=L.getHead();
LinkNode<T>* fast=L.getHead();
while(fast!=NULL&&fast->link!=NULL){
slow=slow->link;
fast=fast->link->link;
cout<<slow->data<<" "<<fast->data<<endl;
if(slow==fast) return true;
}
return false;
}



单链表及其相关函数的程序 包含了单链表的常用操作,如连接、整合、逆序等 立即下载

相关推荐

单链表插入、删除、头插法、尾插法

单链表插入的很好的学习材料,大家都来看看

四道有趣单链表面试题单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)

参考:http://blog.sina.com.cn/s/blog_725dd1010100tr4y.html 四道有趣单链表面试题单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环) 以下给出链表结点的数据结构: template struct LinkNode{   //链表节点 T data; LinkNode* link; LinkNode(LinkNod

行走的天马 1126

单链表及其应用

利用单链表实现电话本的模拟程序:定义单链表的数据类型,将头插法和尾插法、插入、删除、查找、修改、计数、逆置、输出等操作都定义成子函数的形式,最后在主函数中调用它,并将每一种操作前后的结果输出,以查看每一种操作的效果。

数据结构-单链(C语言)

数据结构-单链表。 根据数据结构书上提供的算法,自己实践将单链表的插入,查找,删除等操作编写成系统。可以输入进行相关操作。

四道有趣单链表面试题(转)

<br />原文:http://c.chinaitlab.com/ccjq/794824_2.html<br />链表也算是基本数据类型之一了。记得刚学习C语言的时候,链表和数组是见得最多的数据类型了。也正因为它的常用,在面试的时候自然会有所涉及,本文 主要讨论四道我觉得比较有趣的关于单链表的面试题。 <br />  Q1  链表的反序<br />  Q2  找出链表的中间元素<br />  Q3  链表排序<br />  Q4  判断一个单链表是否有环<br />  以下给出链表结点的数据结构:<br

成长记录 471

四道有趣单链表面试题单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环

四道有趣单链表面试题单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环) () 以下给出链表结点的数据结构:

luyafei_89430的专栏 724

单链表及其实现

单链表及其相关实现,(吉林大学计算机科学与技术学院第一次上机实验课答案)

单链表头插法和尾插法的算法程序

头插法 头插法是用结构体数组来实现的。 具体的思路是:在建立邻接表时,记录的不是点而是边,对于每一个点所对应的邻接表都是以栈的形式存储的,也就是说先添加的边在遍历时后取出,除此以外,所有的边用一个结构体数组存储起来,每条边对应的索引就是其编号,在建立邻接表时,表中存放的实质是边的编号,在遍历时先获得编号,在放回结构体数组中获得相应的边的数据。

数据结构单链表实验

数据结构,单链表实验,对学习数据结构有帮助

四道有趣单链表面试题单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环) ()

http://www.cppblog.com/koson/archive/2010/04/21/113142.html 以下给出链表结点的数据结构: 1  typedef struct _list_node 2 { 3     double keyVal; 4     struct _list_node *next; 5 }ListNode; Q1 单链表的反序

xie_dream的专栏 1557

数据结构与算法⑥(第二章OJ题,下)后八道链表面试题

数据结构与算法⑥(第二章OJ题)后八道链表面试题(力扣:面试题 02.04. 分割链表+234. 回文链表+160. 相交链表+141. 环形链表+142. 环形链表 II+138. 复制带随机指针的链表+147. 对链表进行插入排序 +JZ76 删除链表中重复的结点)

参考书籍:《C语言程序设计》《数据结构》《C++ Primer》《Effective C++》《STL源码剖析》《现代操作系统》《UNIX环境高级编程》《图解TCP/IP》《图解HTTP》《Linux高性能服务器编程》《剑指Offer》《算法导论》 523

单链表专题(三)-刷题复盘篇:从快慢指针到环形链表 II 数学推导

本文复盘单链四道经典面试题:倒数第 k 个节点、回文链表、相交链表与环形链表 II,系统梳理定距双指针、快慢指针、原地反转和长度对齐等核心思路,并分析时间、空间复杂度。重点结合手写笔记推导 Floyd 判环中“为何必然相遇”与“为何第二次相遇即为入环点”,最后补充通用步长与贝祖定理拓展,帮助从会写代码进一步理解算法原理。

Luminousone的博客 598
上一篇: 二叉树遍历(前中后层序/非递归)
下一篇: 轻松搞定面试中的链表题目
vic__vic
博客等级 码龄15年 3粉丝 4原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值