选择排序:每次从剩余数组中选择一个最小的,然后从0开始和相应位置的数字作交换,假设数组长度为n,外层遍历n次,内层查找n-1次,时间复杂度为Θ(n^2):
1 void SelectionSort(int * x,int length) 2 { 3 //外层遍历 4 for(int i = 0;i < length - 1;i++) 5 { 6 //每次遍历查找最小时初始化中间变量 7 int min_value = Max; 8 int min_position = 0; 9 //内层遍历出最小值 10 for(int j = i;j < length;j++) 11 { 12 if(x[j] < min_value) 13 { 14 min_value = x[j]; 15 min_position = j; 16 } 17 } 18 //和相应位置做交换 19 int temp = x[i]; 20 x[i] = min_value; 21 x[min_position] = temp; 22 }
插入排序:和选择排序不同的是,插入排序的内层遍历是依次和已排序好的数组部分作比较,虽然时间复杂度依然是Θ(n^2):
1 void InsertionSort(int * x,int length) 2 { 3 //从第二个还是排序 4 for(int i = 1 ;i < length;i++) 5 { 6 //和当前已排序好的数组部分作比较,如果小于则交换 7 for(int j = i;j > 0 ;j--) 8 { 9 if(x[j] < x[j - 1]) 10 { 11 int temp = x[j]; 12 x[j] = x[j - 1]; 13 x[j - 1] = temp; 14 } 15 } 16 } 17 }
冒泡排序:每次从数组的最后一个元素开始向前遍历,起时间复杂度同上,但是由于冒泡排序的特性(在从最后一个元素冒前面泡的同时,相对后面较小的元素也冒了上来),它的常数因子较小:
1 void BubbleSort(int * x,int length) 2 { 3 //如果你数组是逆序排列,外层需要n次才能让数组顺序排列 4 for(int i = 0 ; i < length;i++) 5 { 6 //每次选择数组的最后一个元素,如果前一个大于当前元素(也就是"泡"),两者交换,也就是较小元素冒了上来 7 //否则,索引前移,继续遍历 8 for(int j = length - 1;j > 0 j++) 9 { 10 if(x[j] < x[j - 1]) 11 { 12 int temp = x[j]; 13 x[j] = x[j - 1]; 14 x[j - 1] = temp; 15 } 16 } 17 } 18 }
这三种排序算法是非常简单的,而且在实际应用中也基本不用,但是通过对它们的理解,可以感受到算法设计的魅力所在。