开发面试题之常见的排序算法-冒泡、选择、插入、希尔
常见的排序算法-时间复杂度和空间复杂度
1、冒泡排序
最简单的一种排序算法。先从数组中找到最大值(或最小值)并放到数组最左端(或最右端),然后在剩下的数字中找到次大值(或次小值),以此类推,直到数组有序排列。算法的时间复杂度为O(n^2)。
// 冒泡排序 -- 每次对相邻节点进行排序,如果顺序不对,就交换数值。每一次排序,最大的节点,都移位到最后一个位置。
public static void BubbleSort(int[] a, int length){
for(int i=0; i<length; i++){
for(int j=0; j<length-i-1; j++){
if(a[j]>a[j+1]){
int tmp = a[j+1];
a[j+1] = a[j];
a[j] = tmp;
}
}
}
}
2、选择排序
严蔚敏版《数据结构》中对选择排序的基本思想描述为:每一趟在n-i+1(i=1,2,...,n-1)个记录中选取关键字最小的记录作为有序序列中第i个记录。具体来说,假设长度为n的数组arr,要按照从小到大排序,那么先从n个数字中找到最小值min1,如果最小值min1的位置不在数组的最左端(也就是min1不等于arr[0]),则将最小值min1和arr[0]交换,接着在剩下的n-1个数字中找到最小值min2,如果最小值min2不等于arr[1],则交换这两个数字,依次类推,直到数组arr有序排列。算法的时间复杂度为O(n^2)。
// 选择排序 -- 每次选择最小的值,放在待排序中的第一位。
public static void SelectionSort(int[] a, int length){
for(int i=0; i< length; i++){
int index = i;
for(int j=i+1; j<length; j++){
if(a[j] < a[index]){
index = j;
}
}
if(index != i){
int tmp = a[i];
a[i] = a[index];
a[index] = tmp;
}
}
}
3、插入排序
基本思想:每次插入一个节点到已排序好的序列中。
插入排序的基本思想就是将无序序列插入到有序序列中。例如要将数组arr=[4,2,8,0,5,1]排序,可以将4看做是一个有序序列(图中用蓝色标出),将[2,8,0,5,1]看做一个无序序列。无序序列中2比4小,于是将2插入到4的左边,此时有序序列变成了[2,4],无序序列变成了[8,0,5,1]。无序序列中8比4大,于是将8插入到4的右边,有序序列变成了[2,4,8],无序序列变成了[0,5,1]。以此类推,最终数组按照从小到大排序。该算法的时间复杂度为O(n^2)。
// 插入排序
public static void InsertSort(int a[], int length){
for(int i=1; i<length; i++){
if(a[i] < a[i-1]){
int tmp = a[i];
int j;
for(j= i - 1; j>=0 && tmp<a[j]; j--){
a[j+1] = a[j]; // 节点往后移
}
a[j+1] = tmp; // 待插入节点 -- 插入正确的位置
}
}
}
4、希尔排序
希尔排序(Shell's Sort)在插入排序算法的基础上进行了改进,算法的时间复杂度与前面几种算法相比有较大的改进。其算法的基本思想是:先将待排记录序列分割成为若干子序列分别进行插入排序,待整个序列中的记录"基本有序"时,再对全体记录进行一次直接插入排序。
相关推荐
要知道时间复杂度只是描述一个增长趋势,复杂度为O的排序算法执行时间不一定比复杂度为O长,因为在计算O时省略了系数、常数、低阶。实际上,在对小规模数据进行排序时,n2的值实际比 knlogn+c还要小。