题目描述
题目链接:牛牛的排序
描述
牛牛试图给一个长度为 n 整数数组排序,即实现一个 void sort(int *array,int n)
输入描述:
第一行输入一个正整数 n ,表示数组长度。
第二行输入 n 个正整数,表示数组中每个元素的值
输出描述:
输出排序后的数组
示例1
输入:5
2 9 8 1 3
输出:1 2 3 8 9
解题分析:
这道题本质上,是考察如何实现给定规格的函数void sort(int *array,int n)
功能。但题目不严谨,只要能够达到排序的目的即可。对于排序功能,就有很多方法可以实现。比如:插入排序、希尔排序、选择排序、冒泡排序、快速排序、归并排序、计数排序、堆排序。下面鉴于此题对于初学者而言,暂时简单介绍几种易于理解的方法!后续其他排序方法,也会在我的博客文章中介绍。
注意:以下都以升序排序为例
思路1 直接插入排序算法:
最开始将第一个数作为有序区间,将有序区间的下一个数,插入到有序的区间,使区间继续有序。此时,再前两个数作为一个有序区间,继续将有序区间的下一个数,插入到有序的区间,使区间继续有序。依次往后,直到最后一个数也插入到前一个有序区间,使得区间有序。最后整个区间有序。
思路2 选择排序算法:
从数据中,找出最小/最大的一个元素下标,和第一个元素交换,接着从剩下的元素中继续这种选择和交换方式,放在次位置,依次如此,最终得到一个有序序列。
思路3 冒泡排序算法:
对相邻的元素进行两两比较,顺序相反则进行交换,这样,每一趟会将最小或最大的元素“浮”到顶端,最终达到完全有序。
思路4 计数排序算法:
通过统计数据元素出现的次数,将次数先映射到开辟的数组中元素对应的相对位置处,然后按将对应数组中的值出现的次数,放入到原始数组,这样就原始数组就是有序的。
思路5 使用qsort库函数:
void qsort( void *base, size_t num, size_t width, int (__cdecl *compare )(const void *elem1, const void *elem2 ) );
代码实现:
方法1
#include <stdio.h>
//假设为升序排序
void InsertSort(int* a,int n)
{
//整体排序:第一个有序区间为【0,0】n个数需要排n-1趟,即控制单趟排序的次数
for (int i = 0; i < n - 1; i++)//这里是n-1,
{
//单趟排序:从end处往前找,如果end处的数据比end+1处的数据大,则往后挪。
//【0,end】区间有序,end+1位置的值插入进去,让【0,end+1】有序
int end = i;//注意end不能等于n-1,否则end+1会越界
int tmp = a[end + 1];//保存end后面的数,防止数据挪动把后一个数覆盖了,无法知道需要插入的数
//2 4 5 6 | 1 3
//1 2 4 5 6 | 3
//有序区间每个元素从后往前与比要插入的元素比较
while (end >= 0)//或者tmp >= a[end]
{
if (a[end] > tmp)
{
a[end + 1] = a[end];
end--;
}
else
{
//tmp >= a[end]或者,tmp比所有的数都要小
//这里需要放入数据到end后一个位置,即a[end + 1] = tmp;
break;//使用break,并都会放入数据,a[end + 1] = tmp;放在循环后面,可以合并这两种情况
}
}
a[end + 1] = tmp;
}
}
int main()
{
int n = 0;
//int arr[255] = {0};
int i = 0;
scanf("%d",&n);
int *arr = (int*)malloc(sizeof(int)*n);
if(arr == NULL)
{
return -1;
}
for(i = 0; i < n; i++)
{
scanf("%d",&arr[i]);
}
InsertSort(arr,n);
for(i = 0;i < n; i++)
{
printf("%d ",arr[i]);
}
free(arr);
arr = NULL;
return 0;
}
/***************************************************************************************/
#include <stdio.h>
void swap(int* a, int* b)
{
int tmp = *a;
*a = *b;
*b = tmp;
}
void insert_sort(int arr[], int sz)
{
//3 | 2 1 0 8 5
//2 3 | 1 0 8 5
//0 1 2 3 | 8 5
int i = 0;
for (i = 0; i