四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
来源:互联网 发布:js怎么用 编辑:程序博客网 时间:2024/06/09 15:34
参考:http://blog.sina.com.cn/s/blog_725dd1010100tr4y.html
四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
以下给出链表结点的数据结构:
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应该刚到中点。这只需要遍历一遍链表就行了,还不用计算链表的长度。
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;
}
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环) (转)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环) (转)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环
- 单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环
- 四道有趣的单链表面试题(转)
- 四道有趣的单链表面试题
- 四道有趣的单链表面试题
- 链表面试题(四)---查找链表的中间节点
- 找出链表的中间元素 与 链表排序
- 如何判断一个链表是否有环,如果有环,并找出环的入口
- 找出链表的中间元素
- 链表面试题----判断一个单链表是否带环,若带环,求入口点和环的长度
- 数据结构之链表面试题汇总(三)判断单链表是否有环、取出环的起始点、得到有环链表中环的长度
- 实现类似QQ单一账户登录,在另一个地方登录后在原登录窗口提示下线
- xzfbPXSOzf
- Android Voip开源客户端比较
- Android开发环境的搭建及HelloWorld
- The connection to adb is down, and a severe error has occured.
- 四道有趣的单链表面试题(单链表反序、找出链表的中间元素、链表排序、判断一个单链表是否有环)
- C# 发送邮件
- Codeforces Round #226 (Div. 2)C. Bear and Prime Numbers
- 《高斯核函数的两点性质》
- win7IIS配置演示(完整版)
- Oracle数据库中char,varchar2,nvarchar2的区别
- dedecms所有标签调用方式大全
- 分组取最值 select top n checksum binary_checksum
- windows键盘快捷键