[C++]歸併排序(連結串列描述)
基本思想
分而治之:通過遞迴把一個無序連結串列對半分成許多小連結串列,然後對這些小連結串列兩兩之間進行歸併(合併有序連結串列),從而最終使整個連結串列有序。
程式碼
#include<iostream>
using namespace std;
template<class T>
struct chainNode//定義連結串列節點
{
T element;
chainNode<T>* next;
chainNode(const T& theElement)
{
next = nullptr;
element = theElement;
}
chainNode(const T& theElement, chainNode<T>* theNext)
{
next = theNext;
element = theElement;
}
};
template<class T>
class chain
{
public:
chain()
{
first = nullptr;
size = 0;
}
void push(const T& theElement)//只提供頭插法
{
first = new chainNode<T>(theElement, first);
size++;
}
void mergeSort() { first = mergeSort(first); }
void print()
{
chainNode<T>* currentNode = first;
while (currentNode != nullptr)
{
cout << currentNode->element << " ";
currentNode = currentNode->next;
}
cout << endl;
}
private:
chainNode<T>* first;
int size;
chainNode<T>* merge(chainNode<T>* head1, chainNode<T>* head2)//合併兩個有序連結串列實現歸併
{
chainNode<T> top(0);//合併連結串列的頭節點,不參與返回
chainNode<T>* currentNode = ⊤
while (head1 != nullptr && head2 != nullptr)//將兩連結串列中較小的一個節點加入到合併連結串列中,直到其中一個連結串列到達結尾
{
if (head1->element < head2->element)
{
currentNode->next = head1;
head1 = head1->next;
}
else
{
currentNode->next = head2;
head2 = head2->next;
}
currentNode = currentNode->next;
}
//之後把未到達結尾的連結串列加入到合併連結串列中
if (head1 != nullptr)
currentNode->next = head1;
if (head2 != nullptr)
currentNode->next = head2;
return top.next;
}
chainNode<T>* mergeSort(chainNode<T>* theFirst)
{
if (theFirst == nullptr || theFirst->next == nullptr)
return theFirst;
chainNode<T>* fastNode = theFirst;
chainNode<T>* slowNode = theFirst;
while (fastNode->next != nullptr&& fastNode->next->next != nullptr)//當快節點到達結尾時,慢節點正好到達連結串列中間
{
slowNode = slowNode->next;
fastNode = fastNode->next->next;
}
chainNode<T>* head2 = slowNode->next;//head2是後半段連結串列的頭節點
slowNode->next = nullptr;//刪除後半段
chainNode<T>* head1 = theFirst;//head1是前半段連結串列的頭節點
head1 = mergeSort(head1);
head2 = mergeSort(head2);
return merge(head1, head2);//返回兩段有序連結串列歸併之後的連結串列
}
};
int main()
{
int n,num;
cin >> n;//n表示連結串列節點個數
chain<int> c;
for (int i = 0; i < n; i++)
{
cin >> num;
c.push(num);
}
c.mergeSort();
c.print();
}
相關文章
- 演算法:排序連結串列:歸併排序演算法排序
- 利用遞迴實現連結串列的排序(歸併排序)遞迴排序
- 淺談歸併排序:合併 K 個升序連結串列的歸併解法排序
- 歸併排序:陣列和連結串列的多種實現排序陣列
- 合併K個排序連結串列排序
- 資料結構實驗之連結串列四:有序連結串列的歸併資料結構
- 連結串列合併-排序-logo列印參考排序Go
- 演算法基礎~連結串列~排序連結串列的合併(k條)演算法排序
- LeetCode 23. 合併K個排序連結串列LeetCode排序
- leetcode23. 合併K個排序連結串列LeetCode排序
- JZ-016-合併兩個排序的連結串列排序
- 148. 排序連結串列排序
- 連結串列-插入排序排序
- 資料結構與演算法——歸併排序: 陣列&連結串列&遞迴&非遞迴解法全家桶資料結構演算法排序陣列遞迴
- 歸併排序排序
- C++快速排序與歸併排序的實現(LeetCode 912)C++排序LeetCode
- Sort排序專題(7)歸併排序(MergeSort)(C++實現)排序C++
- 快速排序&&歸併排序排序
- 反轉連結串列、合併連結串列、樹的子結構
- C++ STL list連結串列C++
- 四、歸併排序 && 快速排序排序
- 單連結串列的排序問題排序
- java歸併排序Java排序
- 每週一資料結構之連結串列(Kotlin描述)資料結構Kotlin
- #反轉連結串列_C++版 #反轉連結串列_Java版 @FDDLCC++Java
- C++連結串列小冊子C++
- leetcode:21. 合併兩個有序連結串列(連結串列,簡單)LeetCode
- [每日一題] 第十八題:合併兩個排序的連結串列每日一題排序
- 基數排序-單連結串列實現【資料結構與演算法分析(c 語言描述)】排序資料結構演算法
- 合併兩個有序連結串列
- 排序演算法__歸併排序排序演算法
- 排序演算法:歸併排序排序演算法
- 排序演算法 - 歸併排序排序演算法
- 排序演算法(歸併排序)排序演算法
- 歸併排序--排序演算法排序演算法
- 歸併排序--二路排序排序
- 歸併排序和基數排序排序
- 資料結構:歸併排序(非遞迴)資料結構排序遞迴