注意两个循环的判断条件,len-1与len-1-i。
稳定平均时间复杂度:O(n2)最好时间复杂度:O(n)在要排序的一组数中,选出最小(或者最大)的一个数与第1个位置的数交换;然后在剩下的数当中再找最小(或者最大)的与第2个位置的数交换,依次类推,直到第n-1个元素(倒数第二个数)和第n个元素(最后一个数)比较为止。
public void select_sort(int[] arr) { int temp, len = arr.length; for (int i = 0; i < len - 1; i++){ int min = i; for (int j = i+1; j < len; j++){ if (arr[j] < arr[min]) { min = j; } } temp = arr[min]; arr[min] = arr[i]; arr[i] = temp; } } 不稳定时间复杂度与输入无关。 当i=1时,需进行n-1次比较;当i=2时,需进行n-2次比较;依次类推,共需要进行的比较次数是(n-1)+(n-2)+…+2+1=n(n-1)/2交换次数:n平均时间复杂度:O(n2)最好时间复杂度:O(n2)插入排序是一种最简单直观的排序算法,它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。
插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。
public void insert_sort(int[] arr) { int len = arr.length; for(int i=1;i<len;i++){ int num = arr[i]; for(int j=i;j>0 && num<arr[j-1];j--){ arr[j] = arr[j-1]; } arr[j] = num; } } 稳定交换次数与数组中倒置元素的数量相同最好情况下N-1次比较和0次交换平均时间复杂度:O(n2)最好时间复杂度:O(n)插入排序的变种,但是非稳定.
希尔排序是基于插入排序的以下两点性质而提出改进方法的:
插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率。但插入排序一般来说是低效的,因插入排序每次只能将数据移动一位。希尔排序的基本思想是:根据某个步长将数据分为几个部分分别排列,最后就是在基本有序的基础上进行插入排序,性能较高。
public void shell_sort(int[] arr){ int len = arr.length; int gap = 1; while(gap<len/3) gap = 3*gap+1; for(;gap>0;gap/=3){ for(int i = gap;i<len;i++){ int num = arr[i]; for(int j=i;j>0 && num<arr[j-gap];j-=gap){ arr[j] = arr[j-gap]; } arr[j] = num; } } } 不稳定时间复杂度受步长(增量)的影响平均时间复杂度:O(n^1.3)最好时间复杂度:O(n)最坏时间复杂度:O(n2)归并(Merge)排序法是将两个(或两个以上)有序表合并成一个新的有序表,即把待排序序列分为若干个子序列,每个子序列是有序的。然后再把有序子序列合并为整体有序序列。
将数组分为最小序列(每个序列中只有1个),然后两两进行归并排序,紧接着再将排序过的2个一组的序列再进行归并排序……
public void merge_sort(int[] arr,int[] res,int start,int end){ if(start>=end) return; int mid = start+(end-start)/2; int start1 = start, end1 = mid; int start2 = mid+1, end2 = end; merge_sort(arr,res,start,mid); merge_sort(arr,res,mid+1;end); int i = start; while(start1<=end1 && start2<=end2){ if(arr[start1]<arr[start2]){ res[i++] = arr[start1++]; }else{ res[i++] = arr[start2++]; } } while(start1<=end1){ res[i++] = arr[start1++]; } while(start2<=end2){ res[i++] = arr[start2++]; } for(int i=start;i<=end;i++){ arr[i] = res[i]; } } 稳定空间复杂度O(n)平均时间复杂度O(nlogn) -堆排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。
堆排涉及两个操作:
建堆:从第一个非叶子结点开始,使用下沉操作来建堆每次移除堆顶元素,并将其堆尾元素移至堆顶,并重新调整堆 //建堆 public void heapSort(int[] arr){ //从第一个非叶子结点开始建堆 int last = arr.length-1; int index = (last-1)/2; for(int i=index;i>=0;i--){ maxifyHeap(arr,i,arr.length-1); } //每次将堆顶元素与堆尾元素交换,并重新建堆 for(int i=arr.length-1;i>0;i--){ int temp = arr[0]; arr[0] = arr[i]; arr[i] = temp; maxifyHeap(arr,0,i-1); } } //调整堆,下沉过程 public void maxifyHeap(int[] arr,int i, int size){ int l_index = i*2+1; while(l_index<size){ int maxChild = arr[l_index]; int max_index = l_index; int r_index = l_index+1; if(r_index<size){ int right = arr[r_index]; if(right>maxChild){ maxChild = right; max_index = r_index; } } if(maxChild>arr[i]){ arr[max_index] = arr[i]; arr[i] = maxChild; i = max_index; l_index = i*2+1; }else break; } } 不稳定平均时间复杂度O(nlogn)适用于找最大/最小的k个数性质:
稳定时间复杂度O(n)空间复杂度O(m)平均情况下桶排序以线性时间运行
https://visualgo.net/en/sorting
稳定时间复杂度O(n+m)空间复杂度O(n+m)其中m数据的最大值减最小值
按位数进行桶排序,一共10个桶。 首先按个位数桶排序,从桶中取出后再按十位数排……
时间复杂度O(n*k),k为最多的位数