zoukankan      html  css  js  c++  java
  • 排序算法2——(希尔、堆、归并)

    一.希尔排序

    算法复杂度:O(nlogn)

    希尔排序也被称为“缩小增量排序”,是一种效率更高的插入排序,步长为1时希尔排序就是插入排序。

    原理:先将待排序的数组元素分成多个子序列(这些子序列是以相对步长为区分单位的,相隔步长相同的元素在同一个组中),使得每个子序列的元素个数相对较少,然后对各个子序列分别进行插入排序,待整个排序序列“基本有序后”,最后再对所有元素进行一次插入排序。

    示例代码如下:

     1 public class shell {
     2     public static void shellSort(int array[]){
     3         int i,j,h,temp;
     4         int length = array.length;
     5         for(h=length/2;h>0;h=h/2){
     6             for(i=h;i<length;i++){
     7                 temp = array[i];
     8                 for(j=i-h;j>=0;j-=h){
     9                     if(temp<array[j])
    10                         array[j+h] = array[j];
    11                     else
    12                         break;
    13                 }
    14                 array[j+h] = temp;
    15             }
    16         }
    17     }
    18     
    19     
    20     public static void main(String[] args){
    21         int a[] = {5,4,9,8,7,6,0,1,3,2};
    22         int len = a.length;
    23         shellSort(a);
    24         for(int i=0;i<len;i++){
    25             System.out.println(a[i]+" ");
    26         }
    27     }
    28 }

    二.堆排序

    算法复杂度:O(nlogn)

    堆是一种特殊的树形结构,每个节点都有一个值,通常提到堆都是指一个棵完全二叉树,根节点的值小于(或大于)两个子节点的值,同时,根节点的两个子树也分别是一个堆。

    原理:对于给定的n个记录,初始时把这些记录看作一棵顺序存储的二叉树,然后将其调整为一个大顶堆,然后将堆的最后一个元素与堆顶元素(即二叉树的根节点)进行交换后,堆的最后一个元素即为最大记录;接着将前(n-1)个元素程序调整为一个大顶堆,再将对顶元素与当前堆的最后一个元素进行交换后得到次大的记录,重复该过程直到调整的堆中只剩一个元素时为止,该元素即为最小记录,此时便可得到一个有序序列。

    堆排序主要包括两个过程:一是构建堆,二是交换堆顶元素与最后一个元素的位置。

    示例程序如下:

     1 public class heap {
     2     public static void HeapAdjust(int[] a,int pos,int len){
     3         int j,temp = a[pos];
     4         for(j = 2*pos + 1; j <= len; j =(2*j + 1)){//a[]中元素的下标是从0开始的。
     5                                                    //如果写成for(j = 2*pos; j <= len; j *= 2) 则表示a[]中元素的下标是从1开始的。
     6             if(j < len && a[j] < a[j+1])
     7                 ++j;
     8             if(temp >= a[j])
     9                 break;
    10             a[pos] = a[j];
    11             pos = j;
    12         }
    13         a[pos] = temp;
    14     }
    15     
    16     public static void HeapSort(int a[]){
    17         int length = a.length;
    18         int i;
    19         for(i = length/2; i >= 0; i--)
    20             HeapAdjust(a, i, length-1);
    21         for(i = length-1; i >= 0; i--){
    22             int tem = a[0];
    23             a[0] = a[i];
    24             a[i] = tem;
    25             HeapAdjust(a, 0, i-1);
    26         }
    27     }
    28     
    29     public static void main(String[] args){
    30         int a[] = {5,4,9,8,7,6,0,1,3,2};
    31         int len = a.length;
    32         HeapSort(a);
    33         for(int i = 0; i < len; i++){
    34             System.out.println(a[i]+" ");
    35         }
    36     }
    37 }

    三.归并排序

    算法复杂度:O(nlogn)

    归并排序是利用递归与分治技术将数据序列划分成越来越小的半子表,再对半子表排序,最后再用递归方法将排序好的半子表合并成越来越大的有序序列。

    原理:对于给定的n个记录,首先将每两个相邻长度为1的子序列进行归并,得到n/2个长度为2或1的有序子序列,再将其两两归并,反复执行此过程直到得到一个有序序列。

    示例程序如下:

     1 public class merge {
     2     public static void Merge(int[] a,int p,int q,int r){
     3         int i,j,k,n1,n2;
     4         n1 = q-p+1;
     5         n2 = r-q;
     6         //创建并初始化左右数组
     7         int[] L = new int[n1];
     8         int[] R = new int[n2];
     9         for(i=0,k=p;i<n1;i++,k++)
    10             L[i] = a[k];
    11         for(j=0,k=q+1;j<n2;j++,k++)
    12             R[j] = a[k];
    13         //主要的排序工作
    14         for(k=p,i=0,j=0;i<n1&&j<n2;k++){
    15             if(L[i]<R[j]){
    16                 a[k] = L[i];
    17                 i++;
    18             }
    19             else{
    20                 a[k] = R[j];
    21                 j++;
    22             }
    23         }
    24         //排序扫尾工作
    25         if(i<n1){
    26             for(j=i;j<n1;j++,k++)
    27                 a[k] = L[j];
    28         }
    29         if(j<n2){
    30             for(i=j;i<n2;i++,k++)
    31                 a[k] =R[i];
    32         }
    33     }
    34     public static void MergeSort(int[] a,int p,int r){
    35         if(p<r){
    36             int q = (p+r)/2;
    37             MergeSort(a,p,q);
    38             MergeSort(a,q+1,r);
    39             Merge(a,p,q,r);
    40         }
    41     }
    42     
    43     public static void main(String[] args){
    44         int a[] = {5,4,9,8,7,6,0,1,3,2};
    45         int len = a.length;
    46         MergeSort(a,0,len-1);
    47         for(int i=0;i<len;i++){
    48             System.out.println(a[i]+" ");
    49         }
    50     }
    51 }
  • 相关阅读:
    Tomcat全攻略
    JAVA必备——13个核心规范
    利用Node.js实现模拟Session验证的登陆
    Android中关于JNI 的学习(六)JNI中注冊方法的实现
    pomelo源代码分析(一)
    怎样解决栈溢出
    String,StringBuffer与StringBuilder的差别??
    ERWin 7.1 和7.2 的官方FTP下载地址
    C/C++中各种类型int、long、double、char表示范围(最大最小值)
    下拉刷新,上拉装载许多其他ListView
  • 原文地址:https://www.cnblogs.com/Eason-S/p/5494294.html
Copyright © 2011-2022 走看看