内排序的方法有许多种,按所用策略不同,可归纳为五类:插入排序、选择排序、交
换排序、归并排序和分配排序。
插入排序:主要包括直接插入排序和希尔排序两种;
选择排序:主要包括直接选择排序和堆排序;
交换排序:主要包括冒泡排序和快速排序;
归并排序:主要包括二路归并(常用的归并排序)和自然归并。
分配排序:主要包括箱排序和基数排序。
今天介绍一下三种简单的排序算法:冒泡排序、插入排序、选择排序
时间复杂度是衡量算法好坏的最重要的标志。
排序的时间复杂度与算法执行中的数据比较次数与数据移动次数密切相关
算法的图形示例 + 算法描述 + 时间复杂度
三种算法的时间复杂度都是 n的平方级的。
1、冒泡排序
该图来自数据结构的课本,之前的一篇文章也用这个图片
算法描述如下:(应该是比较好理解的代码)
void Bubble_Sort(int arr[],int len) {
int i,j,temp;
for(i=n-1,chenge=TRUE; i>=1 && change; i--) { //i记录排序趟次,也即排好序个数
chenge = FALSE;
for(j=0; j<i; j++) {
if(arr[j] > arr[j+1]) {
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
change = TRUE;
}
}
}
}
2、插入排序
//插入排序
void InsertionSort(T a[],int n){
int i,j;
for(i=2; i<=n; i++) { //从第二个开始,a[0]作为哨兵
if(a[i] < a[i-1]) { //只有小于,才进去排序
a[0] = a[i];
a[i] = a[i-1];
for(j=i-2; a[0]<a[j]; j--) //哨兵小于有序的值,
a[j+1] = a[j]; //记录后移
a[j+1] = a[0]; //插入到正确位置
}
}
}
3、选择排序
算法描述:
首先找出最大的元素,将其与 a[n-1]位置交换;
然后在余下的 n-1 个元素中寻找最大的元素,将其与 a[n-2]位置交换,
如此进行下去直至 n 个元素排序完毕。
按照以上的图示和算法描述,是找出最大的元素,也可以找出最小的元素
void SelectionSort(T a[],int n) {
int i,j,k; //分别表示有序区、无序区、无序区中最大的元素指针
T t;
for(i=n-1; i>0; i--) {
k = i;
for(j=0; j<i;j++) { //找出最大的元素a[k]
if(a[j] > a[k])
k = j;
}
if(k != i) { //移动到有序区
t = a[k];
a[k] = a[i];
a[i] = t;
}
}
}