稳定性 : 稳定
时间复杂度 : 最好情况O(N) 最坏情况O(N^2) 平均情况O(N ^2)
空间复杂度 : O(1)
算法思路 :
public static void insertSort(int[] array){
for (int i = 1; i < array.length; i++) {
int tmp = array[i];
int j = i-1;
for (; j >=0 ; j--) {
if (array[j]>tmp){
array[j+1] = array[j];
}else {
break;
}
}
array[j+1] = tmp;
}
}
稳定性 : 不稳定
空间复杂度 : O(1)
算法思路 :
public static void shellsort(int[] array){
int gap = array.length/2;
while (gap>0){
for (int i = gap; i < array.length; i++) {
int tmp = array[i];
int j = i - gap;
for (; j >=0 ; j-=gap) {
if (array[j]>tmp){
array[j+gap] = array[j];
}else{
break;
}
}
array[j+gap] = tmp;
}
gap/=2;
}
}
稳定性 : 稳定
时间复杂度 : 最好情况O(N) 最坏情况O(N^2) 平均情况O(N ^2)
空间复杂度 : O(1)
算法思路 :
public static void bubbleSort(int[] array){
for (int i = 0; i < array.length-1; i++) {
for (int j = 0; j < array.length-1-i; j++) {
if (array[j]>array[j+1]){
int tmp = array[j];
array[j] = array[j+1];
array[j+1] = tmp;
}
}
}
}
稳定性 : 不稳定
时间复杂度 : 最好情况O(N^2) 最坏情况O(N ^2) 平均情况O(N ^2)
空间复杂度 : O(1)
算法思路 :
public static void selectSort(int[] array){
for (int i = 0; i < array.length-1; i++) {
int midIndex = i;
for (int j = i+1; j < array.length; j++) {
if (array[j] < array[midIndex]){
midIndex = j;
}
}
int tmp = array[midIndex];
array[midIndex] = array[i];
array[i] = tmp;
}
}
稳定性 : 不稳定
时间复杂度 : 最好情况O(nlogn) 最坏情况O(nlogn) 平均情况O(n*logn)
空间复杂度 : O(1)
算法思路 :
public static void heapSort(int[] array){
for (int parent = (array.length-1-1)/2; parent>=0 ; parent--) {
siftDown(array,parent,array.length);
}
int end = array.length-1;
while(end>0){
int key = array[0];
array[0] = array[end];
array[end] = key;
siftDown(array,0,end);
end--;
}
}
public static void siftDown(int[] array , int parent,int length){
int child = parent*2+1;
while(child<length){
if (child+1<length&&array[child+1]>array[child]){
child++;
}
if (array[child]>array[parent]){
int tmp = array[child];
array[child] = array[parent];
array[parent] = tmp;
parent = child;
child = parent*2+1;
}else{
break;
}
}
}
稳定性 : 稳定
时间复杂度 : O(nlogn)
空间复杂度 : O(n)
算法思路:
public static void mergeSort(int[] array) {
mergeSortChild(array,0,array.length-1);
}
private static void mergeSortChild(int[] array,int left,int right) {
//防御性编程
if(left >= right) {
return;
}
int mid = (left + right) / 2;
mergeSortChild(array,left,mid);
mergeSortChild(array,mid+1,right);
//开始合并
merge(array,left,mid,right);
}
private static void merge(int[] array, int left, int mid, int right) {
//临时数组
int[] tmpArr = new int[right-left+1];
//tmpArr数组下标
int k = 0;
int s1 = left;
int e1 = mid;
int s2 = mid+1;
int e2 = right;
//当2个段都有数据的时候
while (s1 <= e1 && s2 <= e2) {
if(array[s1] <= array[s2]) {
tmpArr[k++] = array[s1++];
}else {
tmpArr[k++] = array[s2++];
}
}
//一个段走完了 把另一个段的数据 拷贝到临时数组
while (s1 <= e1) {
tmpArr[k++] = array[s1++];
}
while (s2 <= e2) {
tmpArr[k++] = array[s2++];
}
//临时数组当中存储的是有序的数据 -> 拷贝数据到原始数组当中
for (int i = 0; i < k; i++) {
array[i+left] = tmpArr[i];
}
}
稳定性 : 不稳定
时间复杂度 : 最好情况O(nlogn) 最坏情况O(n^2) 平均情况O(nlogn)
空间复杂度 : 最好情况O(logn) 最坏情况O(n) 平均情况O(logn)
算法思路(挖坑法):
选择基准元素:从列表中选择一个元素作为基准(pivot)。选择方式可以是第一个元素、最后一个元素、中间元素或随机元素。
分区:将列表重新排列,使得所有小于基准元素的元素都在基准的左侧,所有大于基准元素的元素都在基准的右侧。基准元素的位置在分区完成后确定。
递归排序:对基准元素左侧和右侧的子列表分别递归地进行快速排序。
合并:由于分区操作是原地进行的,递归结束后整个列表已经有序。
public static void quickSort(int[] array){
quick(array,0,array.length-1);
}
private static void quick(int[] array, int startindex, int endindex) {
if (startindex>=endindex){
return;
}
int par = getpartition(array,startindex,endindex);
quick(array,startindex,par-1);
quick(array,par+1,endindex);
}
private static int getpartition(int[] array, int startindex, int endindex) {
int index = startindex;
int left = startindex;
int right = endindex;
int pivot = array[index];
while (left<right){
while (left<right){
if (array[right]<pivot){
array[index] = array[right];
left++;
index = right;
break;
}else {
right--;
}
}
while (left<right){
if (array[left]>pivot){
array[index] = array[left];
index = left;
right--;
break;
}else {
left++;
}
}
}
array[index] = pivot;
return index;
}