数据结构—插入排序、希尔排序、直接选择排序、堆排序、冒泡排序

七大基于比较的排序算法。
平时的上下文中,如果提到排序,通常指的是排升序(非降序)。
通常意义上的排序,都是指的原地排序(in place sort)。

稳定性:
两个相等的数据,如果经过排序后,排序算法能保证其相对位置不发生变化,则我们称该算法是具备稳定性的排序算法。

1.插入排序
分为有序区间和无序区间,将无序区间的第一个数插入有序区间

时间复杂度:
最好:O(n) 数据有序
平均:O(n^2)
最差:O(n^2) 数据逆序
空间复杂度:
O(1) 没有占用额外空间
稳定性:
稳定

int[] a={…}
a.clone(); 可以完全复制一份数组
Arrays.sort(a); 可以排序数组
Arrays.equals(a,b); 数组的比较需要调用Arrays.equals

public class InsertSort{
public static void insertSort(int[] array){
//有序区间:[0,i)
//无序区间:[i,array.length)
for(int i=1;i<array.length;i++){
int j;
int k=array[i];
for(j=i-1;j>=0;j--){  //从后往前找,最好情况的时间复杂度为O(n),若从前往后找,就破坏了最好情况
if(array[j]<k){
break;
}else if(array[j]=k){    //等于不交换,保证稳定性
break;
}else{
array[j+1]=array[j];
}
}
array[j+1]=k;
}

public static void insertSort1(int[] array){   //对上面代码的优化
for(int i=1;i<array.length;i++){
int j;
int k=array[i];
for(j=i-1;j>=0&&array[j]>k;j--){
array[j+1]=array[j];
}
array[j+1]=k;
}
}
}

2.希尔排序
是对插入排序的优化,在插入排序之前使数组尽可能有序的思想,分组插排
时间复杂度:
最好:O(n)
最坏:O(n^2)
平均:O(n^1.3)
空间复杂度:
O(1)
稳定性:
不稳定 (两个相同的数可能分到不同的组)

public class ShellSort{
public static void shellSort(int[] array){
int gap=array.length;
int k=array[i];      
while(true){
   gap=(gap/3)+1;     //最后一次的区间长度为1
// gap=gap/2
insertSortWithGap(array,gap);
if(gap==1){
break;
}
}
}
public static void inserSortWithGap(int[] array,int gap){
for(int i=gap;i<array.length;i++){
int j;
int k=array[i];
for(j=i-gap;j>=0&&array[j]>k;j-=gap){
array[j+gap]=array[j];
}
array[j+gap]=k;
}
}

3.直接选择排序
每一次从无序区间选出最大(或最小)的一个元素,存放在无序区间的最后(或最前)

时间复杂度:O(n^2) 数据不敏感
空间复杂度:O(1)
稳定性:不稳定

public class SelectSort{
public static void selectSort(int[] array){
   //每次选择最大的数放到最后面
   for(int i=0;i<array.length-1;i++){
   //无序:[0,array.length-i)
   //有序:[array.length-i,array.length)
   int maxIndex=0;
   for(int j=1;j<array.length-i;j++){
   if(array[j]>array[maxIndex])
   maxIndex=j;
   }
   }
   swap(array,maxIndex,array.length-i-1);
   }
   public static void selectSort1(int[] array){
   for(int i=1;i<array.length-1;i++){
   //有序:[0,i)
   //无序:[i,array.length)
   int minIndex=i;
   for(int j=i+1;j<array.length;j++){
   if(array[j]<array[minIndex]){
   minIndex=j;
   }
   }
   swap(array,minIndex,i);
   public static void swap(int[] a;int i;int j){
   int t=a[i];
   a[i]=a[j];
   a[j]=t;
   }
   }

4.堆排序

基本原理也是选择排序,只是不在使用遍历的方式查找无序区间的最大的数,而是通过堆来选择无序区间的最大的
数。
注意: 排升序要建大堆;排降序要建小堆。
时间复杂度:O(n*log(n)) 数据不敏感
空间复杂度:O(1)
稳定性:不稳定

public class HeapSort{
publib static void heapSort(int[] array){
createHeapBig(array);
for(int i=0;i<array.length-1;i++){
//无序:[0,array.length-i)
//交换:array[0],array[array.length-i-1]
//无序:[0,array.length-i-1)
//无序长度:array.length-i-1
//下标0进行向下调整
swap(array,0,array.length-i-1);
shiftDown(array,0,array.length-i-1);
}
}
public static void swap(int[] a;int i;int j){
   int t=a[i];
   a[i]=a[j];
   a[j]=t;
   }

private static void createHeapBig(int[] array){
for(int i=(array.length-2)/2;>=0;i--){
shiftDown(array,i,array.length);
}
}
private static void shiftDownBig(int[] array,int i,int size){
while(2*i+1<size){
int max=2*i+1;
if(max+1<size&&array[max+1]>array[max]){
max=max+1;
}
if(array[i]>array[max]){
return
}
else{
swap(array,i,max);
i=max;
}
}
}
}
}

5.冒泡排序

在无序区间,通过相邻数的比较,将最大的数冒泡到无序区间的最后

时间复杂度:
最好:O(n) 数据有序
最差:O(n^2) 数据逆序
平均:O(n^2)
空间复杂度:O(1)
稳定性:稳定

public class BubbleSort{
public static void swap(int[] a;int i;int j){
   int t=a[i];
   a[i]=a[j];
   a[j]=t;
   }
   
public static void bubbleSort(int[] array){
for(int i=0;i<array.length-1;i++){
boolean isSorted=true;
for(int j=0;j<array.length-i-1;j++){
if(array[j]>array[j+1]{
swap(array,j,j+1);
isSorted=flase;
}
}
if(isSorted){
break;
}
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值