1. 堆排序
/*
* 手动实现堆排序, 使用大根堆实现 从小到大排序
*/
// 完成在数组[low, high]的范围内,对在位置low上的节点向下进行调整
void shift(int nums[], int low, int high) {
int i = low;
int j = i*2;
int tmp = nums[i];
while(j<=high) {
// 比较当前节点的左、右儿子
if(j<high && nums[j]<nums[j+1])
j++; //如果右儿子较大则让j指向较大的儿子节点的下标
if(tmp < nums[j]) {
nums[i] = nums[j];
i = j;
j = i*2;
} else
break;
}
nums[i] = tmp;
}
void heap_sort(int nums[], int n) {
int tmp;
// 建立初始化的堆, 从第一个非叶子结点进行调整
for(int i=n/2; i>=1; i--) {
shift(nums, i, n);
}
// 进行n-1次循环, 完成堆排序, 把堆顶元素放到后面
for(int i=n; i>=2; i--) {
tmp = nums[1];
nums[1] = nums[i];
nums[i] = tmp;
shift(nums, 1, i-1);
}
}
int main()
{
int n;
scanf("%d", &n);
int nums[100];
// 读入n个数据, 堆一棵完全二叉树,必须从1开始存储
for(int i=1; i<=n; i++) {
scanf("%d", &nums[i]);
}
// 进行堆排序
heap_sort(nums, n);
// 打印排序后的数组
for(int i=1; i<=n; i++) {
printf("%d ", nums[i]);
}
return 0;
}
2. 归并排序
/*
* 实现二路归并排序
*/
// 合并函数:原数组、辅助数组、开始下标,中间下标、结束下标
void Merge(int sourceArray[], int tempArray[], int s, int mid, int t)
{
int i = s;
int j = mid+1;
int k = s;
while(i<=mid && j<=t)
{
if(sourceArray[i] <= sourceArray[j])
tempArray[k++] = sourceArray[i++];
else
tempArray[k++] = sourceArray[j++];
}
while(i<=mid)
tempArray[k++] = sourceArray[i++];
while(j<=t)
tempArray[k++] = sourceArray[j++];
for(i=s; i<=t; i++)
sourceArray[i] = tempArray[i];
}
// 原数组,辅助数组,开始下标,结束下标
void MergeSort(int sourceArray[],int tempArray[],int s,int t)
{
if(s<t)
{
int mid = (s+t)>>1;
// 递归排序左边
MergeSort(sourceArray,tempArray,s,mid);
// 递归排序右边
MergeSort(sourceArray,tempArray,mid+1,t);
// 合并
Merge(sourceArray,tempArray,s,mid,t);
}
}