链表面试题-单链表排序(冒泡,快速,归并)
2018-03-15 12:40
288 查看
面试中单链表是一个被问及频率很高的问题,这几天同学面试中多次被问及,所以今天整理一下。
注:对链表排序时,只需要交换结点间的_data即可,如果想法是改变指针,那么只能是走弯路了。
结点类型
冒泡排序:
对于冒泡排序,想必任何一个程序猿都不会陌生。原理就不解释了。
快速排序:
针对于快速排序,我了解三种快速排序的思路。
这里采用前后指针法:
具体的快速排序可见:http://blog.csdn.net/qq_36528114/article/details/78667034
归并排序:
归并的思想还是再提一下:
获取当前序列的中间结点
将当前序列一分为二,然后合并成一个有序单链表
递归上面两步
注:对链表排序时,只需要交换结点间的_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)); }
相关文章推荐
- 链表之排序(插入、选择、归并、快速、冒泡)
- 链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)【转载】
- 链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)
- 链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)
- 经典面试题:Java实现-归并K条已排序的链表及复杂度分析、优化
- 单链表的归并、快速排序 C++
- 排序——冒泡、归并、快速、选择、插入、堆
- 第四篇、C_快速、冒泡、选择、插入排序、二分查找排序、归并、堆排序
- c# 自定义排序类(冒泡、选择、插入、希尔、快速、归并、堆排序等)
- 数据结构各种排序法及核心思想(冒泡、鸡尾酒、选择、插入、二分法、希尔、堆、归并、快速)
- 冒泡、快速、归并排序课程设计
- 链表排序(冒泡、插入、归并和快排)
- 链表排序(冒泡、归并)
- 插入 | 希尔 | 冒泡 | 快速 | 选择 | 归并排序
- 排序算法Java描述:选择、冒泡、插入、希尔、归并、快速及三向切分快速排序
- Python基础----排序(插入、冒泡、快速、归并)
- C/C++ 数组,链表排序(平均时间复杂度 O(nlogn))归并、快速、堆、希尔之归并排序
- 链表排序(冒泡、选择、插入、快排、归并、希尔、堆排序)
- 曾经遇到的一个面试题,快速排序用链表实现,算法和以前的相似,需要注意一些细节处理
- 冒泡,归并,快速排序