基本思想
分而治之:通过递归把一个无序链表对半分成许多小链表,然后对这些小链表两两之间进行归并(合并有序链表),从而最终使整个链表有序。
代码
#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();
}