排序算法 代码 希尔 堆 归并

运行结果:


代码实践:

#include <iostream>
#include <string>

using namespace std;

//希尔排序
//原理与直插法类似,只不过由两两相邻元素相比较 变成 两两以一定间隔元素相比较
void ShellSort(int r[],int n)// n 个元素
{
	int i, j, temp;
	int increment = n;
	do
	{
		increment = increment / 3 + 1;
		for (i = increment; i < n; i++)
		{
			//if之外for之内写r[j] = temp;报错  函数 栈 释放???作用域问题!!!内存管理问题!!!
			if (r[i] < r[i - increment])
			{
				temp = r[i];
				for (j = i - increment; j >= 0 && r[j] > temp; j -= increment)
					r[j + increment] = r[j];
				r[j + increment] = temp;
			}
		}
	} while (increment > 1);
}

//堆排序
//两步  两个函数
//(1)构建什么堆?大顶堆、小顶堆 --- 大顶堆 满足关系:双亲节点的值不小于其大孩子节点的值
//(2)过程:堆首尾元素交换 元素个数-1 对根节点大顶堆重构 循环直到只剩一个元素
//构建大顶堆
void HeapAdjust(int r[], int i, int n)// i 双亲节点   n 总元素个数
{
	int j, temp;

	//对该双亲节点i及其孩子的子树进行处理
	for (j = 2 * i; j < n; j *= 2) 
	{
		temp = r[i];

		//找到该双亲节点的大孩子 j  先假设左孩子值最大
		if ( (j <= n-1) && (r[j + 1] > r[j]) )
			j++;
		//是否满足大顶堆关系式 是则表示该双亲节点的子树符合要求 否则想办法满足大顶堆要求,如交换元素
		if (r[i] >= r[j])
			break;
		else 
		{
			r[i] = r[j];
			//设置该大孩子为下一次循环的双亲节点
			i = j;
		}
		r[j] = temp;
	}
}
//交换 -1 重构建
void HeapSort(int r[],int n)//n 数组元素个数
{

	//(1)对所有的双亲节点进行大顶堆重构
	for (int i = 1; i <= n / 2; i++)
		HeapAdjust(r, i, n);

	//(2)过程:堆首尾元素交换 元素个数-1 对根节点大顶堆重构 循环直到只剩一个元素
	for (int i = n - 1; i > 1; i--)
	{
		swap(r[1], r[i]);
		HeapAdjust(r, 1, i - 1);
	}
}

// 归并排序--归并函数  
void Merge(int* pData, int first, int mid, int last)
{
	//申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列  
	int *pTemp = new int[last - first + 1];
	int begin1 = first, begin2 = mid + 1;
	int i;
	for (i = 0; begin1 <= mid && begin2 <= last; ++i)
	{
		//比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置  
		if (pData[begin1] <= pData[begin2])
			pTemp[i] = pData[begin1++];
		else
			pTemp[i] = pData[begin2++];
	}
	//若有剩余,直接拷贝出来粘到合并序列尾  
	if (begin1 <= mid)
		memcpy_s(pTemp + i, (last - first + 1)*sizeof(int), pData + begin1, (mid - begin1 + 1)*sizeof(int));
	else if (begin2 <= last)
		memcpy_s(pTemp + i, (last - first + 1)*sizeof(int), pData + begin2, (last - begin2 + 1)*sizeof(int));
	//将排序好的序列拷贝回数组中  
	memcpy_s(pData + first, (last - first + 1)*sizeof(int), pTemp, (last - first + 1)*sizeof(int));
	delete pTemp;
}
// 归并排序--回溯函数  
//树 递归求出叶子节点(<=2个) 然后排序回溯 
//思路:分组排序,把排序后的数组归并
void MergeSort(int* pData, int first, int last)
{
	int mid = 0;
	if (first < last)
	{
		mid = (first + last) / 2;
		MergeSort(pData, first, mid);
		MergeSort(pData, mid + 1, last);
		Merge(pData, first, mid, last);
	}
}


int main()
{

	//【01】希尔排序
	int pData1[5] = { 5, 1, 9, 3, 7 };
	ShellSort(pData1, sizeof(pData1) / sizeof(int));
	cout << "希尔排序: ";
	for (int i = 0; i < sizeof(pData1) / sizeof(int); i++)
		cout << pData1[i] << " ";
	cout << endl;

	//【02】堆排序
	int pData2[6] = { 0, 50, 10, 90, 30, 70 };
	HeapSort(pData2, (sizeof(pData2) / sizeof(int)));
	cout << "堆排序: ";
	for (int i = 1; i < 6; i++)
		cout << pData2[i] << " ";
	cout << endl; 


	 //【03】归并排序  
	int pData3[5] = { 500, 100, 900, 300, 700 };
	int first = 0, last = 4;
	MergeSort(pData3, first, last);
	cout << "归并排序: ";
	for (int i = 0; i < 5; i++)
		cout << pData3[i] << " ";
	cout << endl; 



	system("pause");
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值