[C++]归并排序(链表描述)

本文介绍了一种使用模板方法实现的排序算法,通过递归将无序链表对半划分,然后合并有序链表,详细讲解了`mergeSort`函数和`merge`函数的工作原理。通过实例展示了如何利用`push`和`print`方法创建和打印链表,适用于学习链表操作和排序算法的基础理解。
摘要由CSDN通过智能技术生成

基本思想

分而治之:通过递归把一个无序链表对半分成许多小链表,然后对这些小链表两两之间进行归并(合并有序链表),从而最终使整个链表有序。

代码

#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 = &top;
		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();
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值