您的位置:首页 > 职场人生

链表面试题-单链表排序(冒泡,快速,归并)

2018-03-15 12:40 288 查看
面试中单链表是一个被问及频率很高的问题,这几天同学面试中多次被问及,所以今天整理一下。

注:对链表排序时,只需要交换结点间的_data即可,如果想法是改变指针,那么只能是走弯路了。

结点类型

struct Node
{
//构造函数
Node(int data)
:_next(nullptr)
,_data(data)
{}

Node* _next;
int _data;
}


冒泡排序:

对于冒泡排序,想必任何一个程序猿都不会陌生。原理就不解释了。

void BubbleSortList(Node* Head)
{
//空链表或者只有一个节点,则不做处理
if(Head == nullptr || Head->_next == nunllptr)
return;

Node* cur = nullptr;//当前节点
Node* next = nullptr;//下一个节点
Node* tail = nullptr;//链表最后一个节点

while(Head != tail){
cur = Head;
next = cur->_next;
bool flag = false;//如果某一次遍历没有发生交换,则说明已经有序,直接退出
while(cur != tail){
if(cur->_data > next->_data){
std::swap(cur->_data,netx->_data);
flag = ture;
}
cur = next;
next = next->_next;
}
}
if(flag == false)//说明没有发生交换
break;

tail = cur;
}


快速排序:

针对于快速排序,我了解三种快速排序的思路。

这里采用前后指针法:

具体的快速排序可见:http://blog.csdn.net/qq_36528114/article/details/78667034

void QuickSortList(Node* Head,Node* Tail)
{
if(Head == nullptr || Head->_next == nullptr || Head == Tail)
return;

Node* cur = Head->_next;
Node* pre = Head;
int key = Head->_data;//以头节点作为基准值

while(cur != tail){
if(cur->_data < key){
pre = pre->_next;
if(pre != cur){
std::swap(pre->_data,cur->_data);
}
}
cur = cur->_next;
}

std::swap(Head->_data,pre->_data);//将基准值放到枢纽位置
QuickSortList(Head,pre);
QuickSortList(pre->_next,tail);
}


归并排序:

归并的思想还是再提一下:

获取当前序列的中间结点

将当前序列一分为二,然后合并成一个有序单链表

递归上面两步

//快慢指针法
Node* GetMidNode(Node* Head)
{
if(Head == nullptr)
return nullptr;
if(Head->_next == nullptr)
return Head;

Node* Fast = Head->_next;
Node* Slow = Head;
while(Fast && Fast->_netx){
Fast = Fast->_next->_next;
Slow = Slow->_next;
}
return Slow;
}

Node* MergeTwoList(Node* Head1,Node* Head2)
{
if(Head1 == nullptr)
return Head2;
if(Head2 == nullptr)
return Head1;

Node* newHead = nullptr;
//让两个链表较小的头节点作为新链表的头
if(Head1->_data <= Head2->_data){
newHead = Head1;
Head1 = Head->_next;
}else{
newHead = Head2;
Head2 = Head2->_next;
}

Node* cur = newHead;//让newHead一直在链表头部,最后返回
while(Head1 && Head2){
if(Head1->_data <= Head2){
cur->_next = Head1;
cur = cur->_next;
Head1 = Head1->_next;
}else{
cur->_next = Head2;
cur = cur->_next;
Head2 = Head2->_next;
}
}
//链表1没走完
if(Head1)
cur->_next = Head1;

//链表2没走完
if(Head2)
cur->_next = Head2;

return newHead;
}

Node* MergeSortList(Node* Head)
{
if(Head == nullptr)
return nullptr;
if(Head->_next == nullptr)
return Head;

Node* mid = GetMidNode(Head);
//nextPart是另外一个区间的起始
Node* nextPart = nullptr;
if(mid){
nextPart = mid->_next;
mid->_next = nullptr;
}

return MergeTwoList(MergeSortList(Head),MergeSortList(nextPart));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐