简单排序
1、选择排序
假设共N个数,升序排列
核心思想:从0~N-1位置上找到该范围内最小的数,放在下标0位置(最小的数与下标0位置的数交换);
从1~N-1位置上找到该范围内最小的数,放在下标1位置(最小的数与下标1位置的数交换);
从2~N-1位置上找到该范围内最小的数,放在下标2位置(最小的数与下标2位置的数交换);
......
从N-1~N-1位置上找到该范围内最小的数,放在下标N-1位置(最小的数与下标N-1位置的数交换)。
时间复杂度:O(N2) 时间复杂度即评价算法流程有多少次常数时间的操作
假设平均每个位置进行了C次常数操作:
第一趟(0~N-1),共N个数,C * N次常数操作;
第二趟(1~N-1),共N-1个数,C * (N - 1)次常数操作;
第三趟(3~N-1),共N-2个数,C * (N - 2)次常数操作;
......
共:C * N + C * (N - 1) + C * (N - 2) + ... + C * 1
= C * (a N2 + bN + c) 【忽略低阶项,只看高阶项,即为O(N2)】
代码描述:
1 public void selectSort(int[] num){ 2 //执行的每一趟0~N-1 1~N-1 2~N-1 3 for(int i = 0; i < num.length; i++){ 4 5 //每一趟找到从i开始到N-1范围内最小值的下标 6 //minIndex为每一趟找到的最小值的下标 7 int minIndex = i; 8 for(int j = i + 1; j < num.length; j++){ 9 if(num[j] < num[minIndex]) minIndex = j; 10 } 11 12 //最小的数与下标i位置的数交换 13 swap(num, minIndex, i); 14 } 15 }
2、冒泡排序
核心思想:0位置上的数和1位置的数比较,如果0位置上的数更大则交换;
1位置上的数和2位置的数比较,如果1位置上的数更大则交换;
2位置上的数和3位置的数比较,如果2位置上的数更大则交换;
......
N-2位置上的数和N-1位置的数比较,如果N-2位置上的数更大则交换;
这样一趟下来,最大的数就“冒”到了最后N-1位置。
再执行上述过程,第二大的数会冒到N-2位置。
注:从后往前也可以,第一趟让最小数先”冒”到0位置,第二趟让第二小的数“冒”到1位置
时间复杂度:O(N2)
代码描述:
1 public void bubbleSort(int[] num){ 2 //0~N-1 0~N-2 0~N-3 3 for(int i = num.length - 1; i >= 0; i--){ 4 5 //每次从0位置开始相邻的进行比较 6 for(int j = 0; j < i; j++){ 7 if(num[j] > num[j + 1]){ 8 swap(num, j, j + 1); 9 } 10 } 11 } 12 }
3、插入排序
核心思想:类比抓牌(扑克),每来一张牌就从当前位置往前看,插入合适的位置
先0~0排好序,再0~1排好序,再0~2排好序......
每遍历到一个数num[i],依次与前一个数num[i - 1]进行比较,如果num[i]更小则交换顺序,交换顺序后继续与前一个数比较,直到它到了自己应该到的位置
时间复杂度:与输入数组的状态有关
如果一开始就已经排好序了,每次插入的时候都只需要比较,复杂度是O(N)
如果一开始刚好是逆序的,每次插入的时候都要一直与前面的数不停交换,直到交换到0位置,复杂度是O(N2)
时间复杂度按照最差情况估计,所以是O(N2)
代码描述:
1 public static void insertSort(int[] num){ 2 //从1位置开始 3 for(int i = 1; i < num.length; i++){ 4 5 //当前位置的数不停和前一个位置的数比较,如果当前位置的数更小则交换 6 for(int j = i; j - 1 >= 0; j--){ 7 if(num[j] < num[j - 1]){ 8 swap(num, j, j - 1); 9 } 10 } 11 } 12 }
浙公网安备 33010602011771号