几个内部排序算法的总结(JAVA版)

本文详细介绍了多种排序算法,包括直接插入排序、希尔排序、快速排序、冒泡排序、选择排序、堆排序、归并排序和计数排序等。每种算法都提供了具体的实现代码,并对其时间复杂度、空间复杂度及稳定性进行了分析。

插入排序

1、直接插入排序

 

public void insertSort(int[] a){
 for(int i=0;i<a.length;i++){
  int key=a[i];
  int pos=i;
  while(pos>0&&a[pos-1]>key){
   a[pos]=a[pos-1];
   pos--;
  }
  a[pos]=key; 
 }
 for(int i=0;i<a.length;i++){
  System.out.print(a[i]+" ");
 }
}

直接插入排序(Straight Insertion Sort)是一种最简单的排序方法:将一个记录插入到已排好的有序表中,从而得到一个新的、记录数增1 的有序表。

时间复杂度O(n2),空间复杂度O(1),稳定。

2、希尔排序

 

    public static void shellSort(int[] arrays){
        if(arrays == null || arrays.length <= 1){
            return;
        }
        //增量
        int incrementNum = arrays.length/2;
        while(incrementNum >= 1){
            for(int i=0; i < arrays.length; i ++){
                //进行插入排序
                for(int j=i; j<arrays.length-incrementNum; j=j+incrementNum){
                    if(arrays[j] > arrays[j+incrementNum]){
                        int temple = arrays[j];
                        arrays[j] = arrays[j + incrementNum];
                        arrays[j+incrementNum] = temple;
                    }
                }
            }
            //设置新的增量
            incrementNum = incrementNum/2;
        }
        for(int i=0; i < arrays.length; i++){
            System.out.print(arrays[i]+" ");
        }
    }

希尔排序(Shell‘s Sort)又称为“最小增量排序”:先将整个带排记录分割成为若干子序列分别进行直接插入排序,待整个序列中的记录“基本有序”时,再将全体记录进行一次直接插入排序。详细说明:先将要排序的一组数按增量d(d=n/2,n为待排个数)分成若干组,对每组中全部元素进行直接插入排序,然后按d/2增量分组,直至d=1结束。

 

时间复杂度O(n2),不稳定。

快速排序

3、冒泡排序

 

public void bubbleSort(int[] a){
 int temp=0;
 for(int i=0;i<a.length;i++){
  for(int j=i;j<a.length;j++){
   if(a[i]>a[j]){
    temp=a[i];
    a[i]=a[j];
    a[j]=temp;
   }
  }
 }
}

冒泡排序(Bubble Sort)比较简单就不讲了。

 

时间复杂度O(n2),稳定。

4、快速排序

 

public void QuickSort(int[] a,int low,int high){
 int dp;
 if(low<high){
  dp=partition(a,low,high);
  QuickSort(a,low,dp-1);
  QuickSort(a,dp+1,high);
 }
}
public static int partiton(int[] a,int left,int right({
 int pivot=a[left];
 while(left<right){
  while(left<right&&a[right]>=pivot){
   right--;
  }
  if(left<right){
   a[left++]=a[right];
  }
  while(left<right&&a[left<=pivot){
   left++;
  }
  if(left<right){
   a[right--]=a[left];
  }
 } 
 a[left]=pivot;
 return left;
}

 

 

 

 

 

快速排序(Quick Sort)是对冒泡排序的一种改进:通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可分别对这两部分记录继续进行排序,以达到整个序列有序。一趟排序的详细说明:设枢轴记录的关键字为pivotkey,则首先从high所指位置起向前搜索找到第一个关键字小于pivotkey的记录和枢轴记录交换,然后从low所指位置起向后搜索,找到第一个关键字大于pivotkey的记录和枢轴记录交换,重复步骤直到low=high。

时间复杂度O(nlogn),空间复杂度O(logn),不稳定。平均性能最好!!!

选择排序

5、简单选择排序

 

public SelectSort(int[] a){
 int min=0,temp=0;
 for(int i=0;i<a.length;i++){
  min=i;
  for(int j=i+1j<a.length;j++){
   if(a[j]<a[min])
    min=j;
  }
  if(min!=i){
   a[i]<->a[min];
  }
 }
}

选择排序(Simple Selection Sort)是选择关键字最小的记录作为有序序列的第i个记录。

 

时间复杂度O(n2),不稳定。

6、堆排序

 

public void HeapSort(int[] a){
 for(int i=0;i<a.length;i++){
  createMaxHeap(a,a.length-1-i);
  swap(a,0,a.length-1-i);
 }
}
public static void createMaxHeap(int[] a,int last){
 for(int i=(last-1)/2;i>=0;i--){
  int k=i;//保存当前节点
  while(a*k+1<=last){//当前节点存在子节点
   int big=2*k+1;
   if(big<last){//如果右子节点存在
    if(a[big]<<a[big+1])
     big++;
   }
   if(a[k]<a[big]){
    swap(a,k,big);
    k=big;
   }else{
    break;
   }
  }
 }
} 
pubilc static void swap(int[] a,int i,int j){
 if(i==j){
  return;
 }
 a[i]<->a[j];
}

堆排序(Heap Sort)每一趟排序的基本操作将当前无序区的堆顶记录R[1]和该区间的最后一个记录交换,然后将新的无序区调整为堆。

 

时间复杂度O(nlogn),空间复杂度O(1)。

归并排序

7、2路归并排序

 

public void Sort(int[] a,int low,int high){
 int mid=(low+high)/2;
 if(low<high){
  Sort(a,low,mid);//左边
  Sort(a,mid+1,high);//右边
  merge(a,low,mid,high);
 }
}
public void merge(int[] a,int low,int mid,int high){
 int[] temp=new int[high-low+1];
 int i=low;
 int j=high;
 int k=0;
 while(i<=mid&&j<=high){
  if(a[i]<a[j]){
   temp[k++]=a[i++];
  }else{
   temp[k++]=a[j++];
  }
 }//while
 
 while(i<mid){
  temp[k++]=a[i++];
 } 
<pre name="code" class="java"> while(j<high){
  temp[k++]=a[j++];
 }

for(int x=0;x<temp.length;x++){
a[x+low]=temp[x];
}
}

 


 

2路-归并排序(Merging Sort)是将两个有序表合并成一个新的有序表。

 

时间复杂度O(nlogn),空间复杂度O(n),稳定。

计数排序

8、计数排序

 

public CountSort(int[] a){
 int k=a.lenght;
 int[] res=new int[k];
 int count[]=new int[k];
 for(int i=0;i<k;i++){//初始化
  count[i]=0;
 }
 //将数组中的重复的次数
 for(int i=0;i<a.length;i++){
  count[a[i]]=count[a[i]+1];
 }
 for(int i=1;i<k;i++){
  count[i]=count[i]+count[i-1];
 }
 //将数组a中的元素按顺序复制到res中
 for(int i=a.length-1;i>=0;i--){
  res[count[a[i]]-1]=a[i];
  count[a[i]]--;
 }
}

计数排序不需要俩个数之间的对比呦~

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值