常见的各种排序

1 、插入排序(直接插入排序,希尔排序)

2 、交换排序(冒泡排序,快速排序)

3 、选择排序(简单选择排序,堆排序)

4 、归并排序

5、分配排序


1.1 直接插入排序

思想:

N个随机数的数组,假设前n-1个数是有序的(n>=2)。将第n个数插入前面有序的数中,使这些数也是有序的,如此循环,知道全部排好顺序。

实例:


java实现:

public void insertSort(){
     int temp = 0;
     int data[] = {57,68,59,52};
     for(int i=1;i<data.length;i++){
         int j = i-1;
         int temp = data[i];
         for(;j>=0&&temp<data[j];j--){
             data[j+1]  = data[j];
          }
          data[j+1] = temp;//j在前面的for循环中已经减1了
     }
     for(int k = 0;k<data.length;k++){
         System.out.println(data[k]);
     }
}

1.2 希尔排序

思想:将要排序的一组数,按某个增量d(n/2,n为数组的个数)分成若干组,每组中记录的下标相差d,对每组全部元素进行直接插入排序;然后再用一个更小的常量(d/2)对它进行分组,在每组中再进行直接插入排序。当增量(d/2)等于1时,再进行直接插入排序,排序完成。

实例:

<strong><span style="font-size:18px;">java 实现:</span></strong>
<span style="font-size:18px;">public void hellSort(){
    int data[] = {57,68,59,52,72,28,96,33,24,19};
    int temp  = 0;
    double d1 = data.length;
    while(true){
        d1 = Math.ceil(d1/2);//增量减半
        int d = (int)d1;
        for(int i=0;i<d;i++){
            for(int j=i+d;j<data.length;j+=d){
                int k = j-d;
                temp = data[j];
                for(;k>=0;temp<data[k];k-=d){
                    data[k+d] = data[k];
                }
                data[k+d] temp;
            }
        }
        if(d==1)
            break;
    }
    for(int i=0;i<data.length;i++){
        Sytem.out.println(data[i]);
    }
}</span>


2.1 、冒泡排序

思想:

临近的两个数字排序,按照从小到大或者从大到小的顺序进行交换,这样最大或者最小的数字都交换到了最后一位;然后进行第二趟排序。。。,知道进行到倒数第二个数时排序完成。

实例:


java 实现:

public void bubbleSort(){
    int data[] = {21,32,35,17,89,67,42,13,98};
    int temp = 0;
    for(int i=0;i<data.length;i++){
        for(int j=i+1;j<data.length;j++){
            if(data[i]>data[j]){
                temp = data[i];
                data[i] = data[j];
                data[j] = temp;
              }
        }
    }

}

 

2.2、快速排序:

思想:

选一个基准元素:通常选第一个或者最后一个元素作为基准元素,通过一趟排序,将数组分成两部分,一部分比基准元素小,一部分大于等于基准元素。然后用同样的方法递归地排序分好的两部分。

实例:


java实例:

<span style="font-size:18px;">public int getMiddle(int[] data,int low,int high){
     int pivot = data[low];
     while(low<high){
         while(low<high&&data[high]>=pivot){
             high--;
         }
          data[low] = data[high];//比中轴小的记录移动到低端
         while(low<high&&data[low]<pivot){
               low++;
         }
          data[high] = data[low];
    }
    data[low] = pivot;//或者data[high] = pivot;return high;
    return low;
}

public void quickSort(int[] data,int low,int high){
    int middle = getMiddle(data,low,high);
    quickSort(data,low,middle-1);
    quickSort(data,middle+1,high);
}</span>


3.1 简单选择排序

思想:

在要排序的一组数据中,选择最小的一个数和第一个位置交换;然后在剩余的数中选择最小的一个数和第二个数交换;如此循环到最后一个数和倒数第二个数比较时,完成排序。

java 代码:

public void selectSort(){
    int data[]  = {5,32,23,22,26,78,90,56,3};
    int position = 0;
    for(int i=0;i<data.length;i++){
        int j = i+1;
        position = j;
        int temp = data[i];
        for(;j<data.length;j++){//循环找出最小的数
            if(data[j]<temp){
                temp = data[j];//将较小的数放在temp
                position = j;//将较小数的位置放在position
            }
        }
    data[position] = data[i];//将外层循环比较的数付给最小数的位置上
    data[i] = temp;//将外层循环比较数的位置赋上最小的数
    }
    for(int i=0;i<data.length;i++){
        System.out.println(data[i]);
    }
}

3.2 堆排序

思想:

利用大顶堆或者小顶堆的特性,每次从堆中选择最大或最小的元素。

将初始待排元素(r1.....rn)排成大顶堆,此堆为无序的。2、将堆顶元素r1和rn交换,此时得到的新的无序区(r1...rn-1)和有序区rn,r1.....rn-1 都小于rn;然后重复这个过程(在r1....rn-1中间),直到排序完成。

1、构造初始堆

给定一个整形数组a[]={16,7,3,20,17,8},对其进行堆排序。

    首先根据该数组元素构建一个完全二叉树,得到

 
 然后需要构造初始堆,则从最后一个非叶节点开始调整,调整过程如下:

20和16交换后导致16不满足堆的性质,因此需重新调整

这样就得到了初始堆。


2、排序

6不满足堆的性质,因此需重新调整

这样就得到了初始堆。

即每次调整都是从父节点、左孩子节点、右孩子节点三者中选择最大者跟父节点进行交换(交换之后可能造成被交换的孩子节点不满足堆的性质,因此每次交换之后要重新对被交换的孩子节点进行调整)。有了初始堆之后就可以进行排序了。

此时3位于堆顶不满堆的性质,则需调整继续调整

图1(调整堆时3要和16比较,为什么不跟3比较呢,因为是大顶堆,所以要和大的数比较,如果是小顶堆就和小的数比较;),

 这样整个区间便已经有序了。
    从上述过程可知,堆排序其实也是一种选择排序,是一种树形选择排序。只不过直接选择排序中,为了从R[1...n]中选择最大记录,需比较n-1次,然后从R[1...n-2]中选择最大记录需比较n-2次。事实上这n-2次比较中有很多已经在前面的n-1次比较中已经做过,而树形选择排序恰好利用树形的特点保存了部分前面的比较结果,因此可以减少比较次数。对于n个关键字序列,最坏情况下每个节点需比较log2(n)次,因此其最坏情况下时间复杂度为nlogn。堆排序为不稳定排序,不适合记录较少的排序。
















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值