对老师讲的排序方式深入的理解了一遍,还没来得及全部注释,正在逐步完善,与君共勉!
#include <stdio.h>
#define MAX 10typedef int ARR[MAX];
typedef int Elementype;
void swap(ARR arr,int i,int j);//交换参数的数值
void insert(ARR arr);//插入排序
void shell(ARR arr);//希尔排序
void print(ARR arr);//打印函数
void heap(ARR arr);//堆排序主体
void heapadjust(ARR arr,int n,int m);//堆排序初始化函数void mergesort2(ARR arr,int left,int right)//递归的归并排序
void swap(ARR arr,int i,int j)//交换函数
{
int temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
void insert(ARR arr)//插入排序
{
int i,j;
for(i = 1;i < MAX;i++)
{
if(arr[i-1] > arr[i])//判断该位与前一位的大小
{
Elementype temp = arr[i];//记录待判断的位置
for(j = i - 1;j >= 0;j--)
{
if(arr[j] > temp)
arr[j+1] = arr[j];//如果前一个位置大于后一个位置,将前一位覆盖到后一位,循环进行此判断
else
break;
}
arr[j + 1] = temp;//直到不大于待判断位置,将其赋值给此位置的下一位
print(arr);
}
}
}
void shell(ARR arr)//希尔排序,在插入排序的基础上,依次对数组进行再分组,在组内进行插入排序,然后在更少的分组下进行排序,直到组数为一(组数为2^n+或-1,即1,3,5,7,9,15,17.....)
{
int a[] = {1,3,5};//记录组数
int k = 2;
int step = a[k];//在下一次循环使用不同的组数
int i,j;
while(k >= 0)
{
for(i = step;i < MAX;i++)
{
if (arr[i - step] > arr[i])//如分成五组,第0位和第5位为一组,进行排序,第1位和第6位为一组,进行排序......
{
Elementype temp = arr[i];
for(j = i-step;j >= 0;j -= step)//步长为组数,同一组间两个元素相隔step,判断使用插入排序的思想
{
if(arr[j] > temp)
{
arr[j + step] = arr[j];
}
else
break;
}
arr[j+step] = temp;
}
}
step = a[--k];//进行下一个组数的插入排序
print(arr);
}
}
void heapadjust(ARR arr,int n,int m)
{
Elementype temp = arr[n];//记录父母的值
int i;
for(i = 2*n+1;i <= m;i = 2*i+1)
{
if(i < m && arr[i] < arr[i + 1])//左右子树比较大小
i++;
if(arr[i] < temp)//较大的和父母进行比较
break;
arr[n] = arr[i];//如果孩子大,孩子覆盖父母
n = i;
}
arr[n] = temp;//将较小的父母的值放在孩子的位置
}void heap(ARR arr)
{
int i;
for(i = (MAX-2)/2;i >= 0;i--)//初始化
{
heapadjust(arr,i,MAX-1);//堆处理,最终形成大顶堆
}
print(arr);
printf("**************\n");
for(i = MAX-1;i > 0;i--)
{
swap(arr,0,i);//将最大值放到最后
heapadjust(arr,0,i-1);//缩小树的范围再次形成大顶堆(排除最大值)
print(arr);
}
}void meige(ARR arr,int left,int mid,int right)//归并
{
int len = right-left+1;
Elementype temp[len];
int k = 0;
int i = left;//前一个小组的第一个
int j = mid+1;//后一个小组的第一个
while(i <= mid && j <= right)
{
if(arr[i] < arr[j])
{
temp[k++] = arr[i++];//第一个数进行比较,小的放入数组,然后拿下一个数进行比较
}
else
{
temp[k++] = arr[j++];//比如第一个数比下一组第一个小,放入数组后,i++即后一个与下一组比较,由于组内排序完成,所以只需排组与组之间的数
}
}
while(i <= mid)
{
temp[k++] = arr[i++];//把剩下的数放入数组
}
while(j <= right)
{
temp[k++] = arr[j++];//把剩下的数放入数组
}
for(i = 0;i < len;i++)
arr[left+i] = temp[i];//把临时的数组放入原数组
}void mergesort1(ARR arr)//非递归的归并排序
{
int left,right,mid;
int i;
for(i = 1;i < MAX;i *= 2)
{
left = 0;
while(left + i < MAX)//约束条件为数组中至少还能组成一组进行排序
{
mid = left+i-1;//i为每组的长度,mid的为第一租的尾标
right = (mid+i)<(MAX-1)?(mid+i):(MAX-1);//right为第二组的尾标
merge(arr,left,mid,right);//调用归并函数,把连续两组间的大小排出,第一次是相邻元素的排序,第二次是两个一组,组与组的排序
left = right+1;
}
print(arr);
}
}void mergesort2(ARR arr,int left,int right)//递归的归并排序,思想在组内进行归并排序,然后在组与组间进行归并排序
{
if(left == right)
{
return;
}
int mid = (left+right)/2;
mergesort2(arr,left,mid);//左半组进行组内排序,逐步调用到元素之间的排序并将返回值依次调用
mergesort2(arr,mid+1,right);
merge(arr,left,mid,right);//调用归并排序函数
print(arr);
}