希尔排序算法:https://www.cnblogs.com/chengxiao/p/6104371.html
八大排序算法:https://www.cnblogs.com/RainyBear/p/5258483.html
堆排序算法:https://www.cnblogs.com/jingmoxukong/p/4303826.html
#include <iostream>
using namespace std;
void print(int *data, int len)
{
for (int i = 0;i < 10;++i)
{
cout << data[i] << " ";
}
cout << endl;
}
void bubble_sort(int *data, int len)//冒泡排序
{
for (int i = 0;i < len;++i)
{
for (int j = 0;j < len-1;++j)
{
if (data[j] > data[j + 1])
{
int temp = data[j];
data[j] = data[j + 1];
data[j + 1] = temp;
}
}
}
}
void select_sort(int *data, int len)//选择排序
{
for (int i = 0;i < len-1;++i)
{
int min = i;
for (int j = i + 1;j < len;++j)
{
if (data[min] > data[j])
{
min = j;//交换
}
}
if (min != i)
{
int t = data[min];
data[min] = data[i];
data[i] = t;
}
}
}
void insert_sort(int *data, int len)//插入法排序
{
for (int i = 1;i < len;++i)
{
for (int j = i;j > 0 && data[j - 1] > data[j];--j)
{
int temp = data[j - 1];
data[j - 1] = data[j];
data[j] = temp;
}
}
}
//根据当前增量进行插入排序
void shellInsert(int data[], int len, int dk)//dk为增量
{
int j, temp;
for (int i = dk;i < len;i++)//分别向每组的有序区域插入
{
temp = data[i];
for (j = i - dk;(j >= i % dk) && data[j] > temp;j -= dk)//比较与记录后移同时进行
{
data[j + dk] = data[j];
}
if (j != i - dk)
{
data[j + dk] = temp;//插入
}
}
}
void shell_sort(int data[], int len)//希尔排序
{
int t = 0;
int tlen = len;
while (tlen != 1)//计算趟数
{
tlen = tlen / 2;
t++;
}
int dk = len;
for (int i = 1;i <= t;i++)
{
dk = dk / 2;//计算Hibbard增量
shellInsert(data, len, dk);
}
}
int Partion(int *arr, int low, int high)//一次快排
{
int tmp = arr[low];//基准
while (low<high)
{
while (low < high&&arr[high] >= tmp)
{
--high;
}
if (low >= high)
{
break;
}
else
{
arr[low] = arr[high];
}
while (low < high&&arr[low] <= tmp)
{
low++;
}
if (low >= high)
{
break;
}
else
{
arr[high] = arr[low];
}
}
arr[low] = tmp;
return low;
}
void Quick(int *arr, int start, int end)
{
int par = Partion(arr, start, end);
if (par > start + 1)//如果左边有两个数据以上
{
Quick(arr, start, par - 1);
}
if (par < end - 1)//如果右边有两个数据以上
{
Quick(arr, par + 1, end);
}
}
void quick_sort(int *arr, int len)
{
Quick(arr, 0, len - 1);
}
void Qsort(int a[], int low, int high)
{
if (low >= high)
{
return;
}
int first = low;
int last = high;
int key = a[first];/*用字表的第一个记录作为枢轴*/
while (first < last)
{
while (first < last && a[last] >= key)
{
--last;
}
a[first] = a[last];/*将比第一个小的移到低端*/
while (first < last && a[first] <= key)
{
++first;
}
a[last] = a[first];
/*将比第一个大的移到高端*/
}
a[first] = key;/*枢轴记录到位*/
Qsort(a, low, first - 1);
Qsort(a, first + 1, high);
}
void merge(int a[], int l1, int r1, int l2, int r2)//将两个有序子数列合并。
{
int i = l1;
int j = l2;
int temp[100];
int index = 0;
while (i <= r1&&j <= r2)
{
if (a[i] <= a[j])
{
temp[index++] = a[i++];
}
else
{
temp[index++] = a[j++];
}
}
while (i <= r1) temp[index++] = a[i++];
while (j <= r2) temp[index++] = a[j++];
for (int i = 0;i<index;i++)
{
a[l1 + i] = temp[i];
}
}
void merge_sort(int a[], int left, int right)//归并排序算法
{
if (left<right)
{
int mid = (left + right) / 2;
merge_sort(a, left, mid);
merge_sort(a, mid + 1, right);
merge(a, left, mid, mid + 1, right);
}
}
int maxbit(int data[], int n) //辅助函数,求数据的最大位数
{
int d = 1; //保存最大的位数
int p = 10;
for (int i = 0; i < n; ++i)
{
if (data[i] >= p)
{
p *= 10;
++d;
}
}
return d;
}
//此函数的目的是取得数据每个位上的数值
//i为待取的数据
int getDigit(int i, int d) //d的值为1、2、3...,表示要求取的相应位的值,1表示求取个位,
{ //2表示十分位,类推
int val;
while (d--)
{
val = i % 10;
i /= 10;
}
return val;
}
//基数排序算法的具体实现
void radix_sort(int *list, int begin, int end, int digit)
{
int radix = 10; //基数
int i = 0, j = 0;
int * count = new int[radix]; //存放各个桶的数据存放个数//int count[10];
int * bucket = new int[end - begin + 1];//bucket桶//int bucket[10];
for (int d = 1; d <= digit; d++)
{
for (i = 0; i < radix; i++)
{
count[i] = 0; //置空各个桶的统计数据
}
for (i = begin; i <= end; i++)//统计每个桶中元素个数
{
j = getDigit(list[i], d);
count[j]++;
}
for (i = 1; i < radix; i++)
{
count[i] = count[i] + count[i - 1]; //count[i]表示第i个桶的右边界索引
}
//将数据依次装入桶中,保证数据的稳定性,此步即为基数排序的分配
for (i = end; i >= begin; i--)
{
j = getDigit(list[i], d);
bucket[count[j] - 1] = list[i];
count[j]--;
}
//基数排序的收集
//把桶中的数据再倒出来
for (i = begin, j = 0; i <= end; i++, j++)
{
list[i] = bucket[j];
}
}
}
//array是待调整的堆数组,i是待调整的数组元素的位置,nlength是数组的长度
//本函数功能是:根据数组array构建大根堆
/*
设当前元素在数组中以R[i]表示,那么,
(1) 它的左孩子结点是:R[2*i+1];
(2) 它的右孩子结点是:R[2*i+2];
(3) 它的父结点是:R[(i-1)/2];
(4) R[i] <= R[2*i+1] 且 R[i] <= R[2i+2]。
*/
void HeapAdjust(int array[], int i, int nLength)//i<<=>>parent
{
int nChild;
int nTemp;
for (; 2 * i + 1 < nLength;i = nChild)
{
//子结点的位置=2*(父结点位置)+1
nChild = 2 * i + 1;
//得到子结点中较大的结点
if (nChild < nLength - 1 && array[nChild + 1] > array[nChild]) ++nChild;
//如果较大的子结点大于父结点那么把较大的子结点往上移动,替换它的父结点
if (array[i] < array[nChild])
{
nTemp = array[i];
array[i] = array[nChild];
array[nChild] = nTemp;
}
else break; //否则退出循环
}
}
//堆排序算法
void heap_sort(int array[], int length)
{
int i;
//调整序列的前半部分元素,调整完之后第一个元素是序列的最大的元素
//length/2-1是最后一个非叶节点,此处"/"为整除
for (i = length / 2 - 1;i >= 0;--i)
HeapAdjust(array, i, length);
//从最后一个元素开始对序列进行调整,不断的缩小调整的范围直到第一个元素
for (i = length - 1;i > 0;--i)
{
//把第一个元素和当前的最后一个元素交换,
//保证当前的最后一个位置的元素都是在现在的这个序列之中最大的
array[i] = array[0] ^ array[i];
array[0] = array[0] ^ array[i];
array[i] = array[0] ^ array[i];
//不断缩小调整heap的范围,每一次调整完毕保证第一个元素是当前序列的最大值
HeapAdjust(array, 0, i);
}
}
void main()
{
int data[10] = {45,12,36,89,7,6,32,63,100,1};
print(data,10);
//1.bubble_sort(data,10);//冒泡排序
//2.select_sort(data,10);//选择法排序
//3.insert_sort(data, 10);//插入法排序
//4.shell_sort(data, 10);//希尔排序算法
//5.quick_sort(data,10);//快速排序算法
//5.Qsort(data,0,9);//快速排序算法
//6.merge_sort(data,0,9);//归并排序算法
//7.radix_sort(data,0,9,maxbit(data,10));//桶排序
heap_sort(data,10);//堆排序
print(data,10);
}