//插入排序,平均O(n^2),最好O(n),最坏O(n^2),每次都将当前元素插入到左侧已经排序的数组中,使得插入之后左侧数组依然有序//插入排序每次只能交换相邻元素,令逆序对减少1,因为插入排序需要交换的次数为逆序数量//插入排序的时间复杂度取决于数组的初始顺序,如果数组已经部分有序了,那么逆序较少,需要的交换次数也就较少,时间复杂度较低//从右边换到左边,左边是有序,只要碰到左边是比自己小的,就不用交换下去了,因为更左边只会更小 //稳定 voidInsertion_sort(vector<int>& nums){for(int i =1; i < nums.size();++i){for(int j = i; j >0;--j){if(nums[j]>= nums[j-1])break;swap(nums[j],nums[j-1]);}}}
希尔排序
//希尔排序,插排很慢,因为只能交换相邻的元素,每次只能将逆序数量减少1,希尔排序就是为了解决插排的局限性,通过交换不相邻的元素,每次可以将逆序数量减少大于1//希尔排序使用插入排序对间隔h的序列进行排序,通过不断减小h,最后令h=1,就可以使得整个数组是有序的//希尔排序的时间复杂度是O(nlogn)到O(n^2)之间,达不到平方级别,但是另外几种高级排序只会比希尔排序快2倍左右//不稳定 voidShell_sort(vector<int>& nums){int h =1;while(h < nums.size()/3){
h =3*h+1;}while(h >=1){for(int i = h ; i < nums.size();++i){for(int j = i; j >= h; j-=h){if(nums[j]>= nums[j-h])break;swap(nums[j],nums[j-h]);}}
h = h/3;}}