运行结果:
代码实践:
#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;
}