实例要求:编程实现将输入的数字从小到大排序
直接插入排序:
插入排序是把一个记录插入到已排序的有序序列中,使整个序列在插入该记录后仍然有序。直接插入的确定方法是将待插入的记录与有序区中的各记录自右向左依次比较其关键字值的大小。代码如下:
void insort(int s[], int n) /*自定义函数isort*/
{
int i, j;
for (i = 2; i <= n; i++) /*数组下标从2开始,0做监视哨,1一个数据无可比性*/
{
s[0] = s[i]; /*给监视哨赋值*/
j = i - 1; /*确定要进行比较的元素的最右边位置*/
while (s[0] < s[j])
{
s[j + 1] = s[j]; /*数据右移*/
j--; /*移向左边一个未比较的数*/
}
s[j + 1] = s[0]; /*在确定的位置插入s[i]*/
}
}
希尔排序:
希尔排序是在直接插入排序的基础上做的改进,将排序的序列按照固定增量进行分组,等距离在同一组内进行直接插入排序.这里的算法采用n/2,以后每次缩小到原来的一半。代码如下:
void shsort(int s[], int n) /*自定义函数shsort*/
{
int i, j, d;
d = n / 2; /*确定固定增量值*/
while (d >= 1)
{
for (i = d + 1; i <= n; i++) /*数组下标从d+1开始进行直接插入排序*/
{
s[0] = s[i]; /*设置监视哨*/
j = i - d; /*确定要进行比较的元素的最右边位置*/
while ((j > 0) && (s[0] < s[j]))
{
s[j + d] = s[j]; /*数据右移*/
j = j - d; /*向左移d个位置*/
}
s[j + d] = s[0]; /*在确定的位置插入s[i]*/
}
d = d / 2; /*增量变为原来的一半*/
}
}
冒泡排序:
冒泡排序的思想:如果要对n个数进行冒泡排序,那么要进行n-1趟比较,在第1趟比较中就要进行n-1次两两比较,在第j趟比较中要进行n-j次两两比较。故使用两次for循环。代码如下:
void main()
{
int i, j, t, a[11]; /*定义变量及数组为基本整型*/
printf("请输入10个数:\n");
for (i = 1; i < 11; i++)
scanf("%d", &a[i]); /*从键盘中输入10个数*/
for (i = 1; i < 10; i++) /*变量i代表比较的趟数*/
for (j = 1; j < 11-i; j++) /*变量j代表每趟两两比较的次数*/
if (a[j] > a[j + 1])
{
t = a[j]; /*利用中间变量实现俩值互换*/
a[j] = a[j + 1];
a[j + 1] = t;
}
printf("排序后的顺序是:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); /*将冒泡排序后的顺序输出*/
printf("\n");
}
快速排序:
快速排序是冒泡排序的一种改进,主要的算法是思想是在待排序的n个数据中取第一个数据作为基准值,将所有记录分为三组,第一组中数据小于等于基准值,第二组等于,第三组大于等于,这就完成了第一次分割,然后依次对第一组和第三组分别重复.代码如下:
void qusort(int s[], int start, int end) /*自定义函数qusort()*/
{
int i, j; /*定义变量为基本整型*/
i = start; /*将每组首个元素赋给i*/
j = end; /*将每组末尾元素赋给j*/
s[0] = s[start]; /*设置基准值*/
while (i < j)
{
while (i < j && s[0] < s[j])
j--; /*位置左移*/
if (i < j)
{
s[i] = s[j]; /*将s[j]放到s[i]的位置上*/
i++; /*位置右移*/
}
while (i < j && s[i] <= s[0])
i++; /*位置右移*/
if (i < j)
{
s[j] = s[i]; /*将大于基准值的s[j]放到s[i]位置*/
j--; /*位置右移*/
}
}
s[i] = s[0]; /*将基准值放入指定位置*/
if (start < i)
qusort(s, start, j - 1); /*对分割出的部分递归调用函数qusort()*/
if (i < end)
qusort(s, j + 1, end);
}
选择排序:
选择排序是从待排序的区间中经过选择交换后选出最小值放到a[0],再从剩下的待排序区间中选择交换剩下的最小值放到a[1],以此类推,代码如下:
void main()
{
int i, j, t, a[11]; /*定义变量及数组为基本整型*/
printf("请输入10个数:\n");
for (i = 1; i < 11; i++)
scanf("%d", &a[i]); /*从键盘中输入要排序的10个数字*/
for (i = 1; i <= 9; i++)
for (j = i + 1; j <= 10; j++)
if (a[i] > a[j]) /*如果后一个数比前一个数大则利用中间变量t实现俩值互换*/
{
t = a[i];
a[i] = a[j];
a[j] = t;
}
printf("排序后的顺序是:\n");
for (i = 1; i <= 10; i++)
printf("%5d", a[i]); /*将排好序的数组输出*/
printf("\n");
}
归并排序:
归并排序是将两个或多个有序序列合并成一个有序序列。本案例是二路归并,基本方法如下:
1)将n个记录看成是n个长度为1的有序子表
2)将两两相邻的有序子表进行归并
3)重复执行步骤(2),直到归并成一个长度为n的有序序列
具体代码如下:
void merge(int r[], int s[], int x1, int x2, int x3) /*实现一次归并排序函数*/
{
int i, j, k;
i = x1; /*第一部分的开始位置*/
j = x2 + 1; /*第二部分的开始位置*/
k = x1;
while ((i <= x2) && (j <= x3))
/*当i和j都在两个要合并的部分中*/
if (r[i] <= r[j])
/*筛选两部分中较小的元素放到数组s中*/
{
s[k] = r[i];
i++;
k++;
}
else
{
s[k] = r[j];
j++;
k++;
}
while (i <= x2)
/*将x1~x2范围内的未比较的数顺次加到数组r中*/
s[k++] = r[i++];
while (j <= x3)
/*将x2+1~x3范围内的未比较的数顺次加到数组r中*/
s[k++] = r[j++];
}
void merge_sort(int r[], int s[], int m, int n)
{
int p;
int t[20];
if (m == n)
s[m] = r[m];
else
{
p = (m + n) / 2;
merge_sort(r, t, m, p);
/*递归调用merge_sort函数将r[m]~r[p]归并成有序的t[m]~t[p]*/
merge_sort(r, t, p + 1, n); /*递归调用merge_sort函数将r[p
+1]~r[n]归并成有序的t[p+1]~t[n]*/
merge(t, s, m, p, n); /*调用函数将前两部分归并到s[m]~s[n]*/
}
}