zoukankan      html  css  js  c++  java
  • 排序

      1 package sort;
      2 /**
      3  * 插入排序
      4  * 1)直接插入排序
      5  * 2)折半插入排序
      6  * 3)希尔排序
      7  * 
      8  * 选择排序
      9  * 1)简单选择排序
     10  * 2)堆排序
     11  * 
     12  * 交换排序
     13  * 1)起泡排序
     14  * 2)快速排序
     15  * 
     16  * 归并排序
     17  */
     18 public class sorts {
     19     /**
     20      * 直接插入排序    稳定排序   
     21      * 空间复杂度:o(1)
     22      * 时间复杂度:
     23      * 最坏情况: o(n^2)
     24      * 最好情况: o(n)  
     25      * 平均情况: o(n^2)
     26      * @param data  待排数据数组
     27      */
     28     public static void InsertSort(int[] data){
     29         
     30         for(int i = 1; i < data.length; i++){//数组下标从0开始,第一个元素有序,所以从第二个开始处理
     31             int tmp = data[i];//用来临时存放待排元素
     32             int j = i - 1;//标记开始比较的位置
     33             //完成了从待排元素之前的元素开始扫描,如果大于待排元素,则后移一位
     34             while(j >= 0 && tmp < data[j]){
     35                 data[j+1] = data[j];
     36                 --j;
     37             }
     38             data[j+1] = tmp;//找到插入位置,将tmp中暂存的待排元素插入
     39         }
     40     }
     41     
     42     
     43     
     44     /**
     45      * 折半插入排序   稳定排序    折半查找法的基本要求是序列已经基本有序
     46      * 空间复杂度:o(1)
     47      * 时间复杂度:
     48      * 最坏情况: o(n^2)
     49      * 最好情况: o(n)  
     50      * 平均情况: o(n^2)
     51      * @param data  待排数据数组
     52      */
     53     public static void binaryInsertSort(int[] data){
     54 
     55         for(int i = 1; i < data.length; i++){//数组下标从0开始,第一个元素有序,所以从第二个开始处理
     56             int tmp = data[i];
     57             int low = 0;
     58             int high = i - 1;
     59             while(low <= high){//当low > high  折半查找结束
     60                 int mid = (low + high) / 2;
     61                 if(tmp < data[mid]){
     62                     high = mid - 1; // 插入点在低半区
     63                 }else{ //关键字相同时,使low = mid + 1,到高半区,保证稳定性
     64                     low = mid + 1;// 插入点在高半区
     65                 }
     66             }
     67             //依次向后移动记录
     68             for(int t = i-1; t > high; t--){// 记录后移
     69                 data[t+1] = data[t];
     70             }
     71             data[high+1] = tmp; // 插入
     72         }
     73     }
     74     
     75     /**
     76      * 冒泡(起泡)排序   稳定排序  
     77      * 空间复杂度:o(1) tmp
     78      * 时间复杂度:
     79      * 最坏情况: o(n^2)
     80      * 最好情况: o(n)  
     81      * 平均情况: o(n^2)
     82      * @param data    待排数据数组
     83      */
     84     public static void BubbleSort(int[] data){
     85         int n = data.length;
     86         for(int k = 0; k < n-1; k++){//进行(n-1)趟冒泡
     87             boolean flag = false;//变量flag用来标记本趟排序是否发生交换
     88             for(int i = 1; i < n-k; i++){
     89                 if(data[i-1] > data[i]){
     90                     int tmp = data[i];
     91                     data[i] = data[i-1];
     92                     data[i-1] = tmp;
     93                     flag = true;//如果没发生交换,则flag为false,否则为true
     94                 }
     95             }
     96             if(!flag){
     97                 return;
     98             }
     99         }
    100     }
    101     
    102     /**
    103      * 快速排序    对从data[l]到data[r]的元素进行排序      通常都选取第一个元素作为枢纽
    104      * 空间复杂度:o(logn)  快速排序是递归进行的, 递归需要栈的辅助
    105      * 时间复杂度:
    106      * 最坏情况: o(n^2)
    107      * 最好情况: o(nlogn)  
    108      * 平均情况: o(nlogn)  就平均时间而言,快速排序是所有排序算法中最好的  快速排序的排序趟数和初始序列有关
    109      * @param data    待排数据数组
    110       * @param l    待排数据数组起始位置
    111      * @param r 待排数据数组终止位置
    112      */
    113     public static void QuickSort(int[] data, int l, int r){
    114         
    115         int i = l;
    116         int j = r;
    117         if(l < r){//l >= r  相当于递归终止条件
    118             int tmp = data[l];
    119             //下面这个循环完成了一趟排序,即将数组中小于等于tmp的元素放在左边,大于等于tmp的元素放在右边
    120             while(i != j){
    121                 while(j>i&&data[j]>=tmp) --j;//从右到左扫描找到一个小于tmp的元素
    122                 if(i<j){
    123                     data[i] = data[j];
    124                     i++;
    125                 }
    126                 while(j>i&&data[i]<=tmp) i++;
    127                 if(i<j){
    128                     data[j] = data[i];
    129                     j--;
    130                 }
    131             }
    132             data[i] = tmp;
    133             QuickSort(data, l, i-1);//递归地对tmp左边元素进行排序
    134             QuickSort(data, i+1, r);//递归地对tmp右边元素进行排序
    135         }
    136     } 
    137     
    138     /**
    139      * 简单选择排序    从头到尾顺序扫描序列,找出最小的一个记录,和第一个记录交换,接着从剩下的记录中继续这种选择和交换,最终使序列有序   
    140      * 空间复杂度:o(1)  tmp
    141      * 时间复杂度:o(n^2)
    142      * @param data    待排数据数组
    143      */
    144     public static void SelectSort(int[] data, int n){
    145         for(int i = 0; i < (n-1); i++){
    146             int k = i;//k用来记录最小值的位置 
    147             for(int j = i + 1; j < n; j++){
    148                 if(data[j] < data[k]){
    149                     k = j;
    150                 }
    151             }
    152             if(k != i){
    153                 int tmp = data[k];
    154                 data[k] = data[i];
    155                 data[i] = tmp;
    156             }
    157             
    158         }
    159     }
    160 }

    折半插入排序:
      与直接插入排序相比,折半插入排序寻找插入位置上面所花的时间大大减少。折半插入排序在记录移动次数方面和直接插入排序是一样的,所以时间复杂度和直接插入排序还是一样的。

    希尔排序:
      又叫做缩小增量排序,其本质是插入排序,只不过是将待排序的序列按某种规则分成几个子序列,分别对这几个子序列进行直接插入排序。
    希尔排序是不稳定的排序
    空间复杂度:o(1)
    平均情况下时间复杂度: o(nlogn)
    注意:希尔排序的增量取法要注意,首先增量序列的最后一个值一定是1; 其次增量序列中的值没有除1之外的公因子,如8、4、2、1这样的序列就不要取(8、4、2有公共因子2)

    堆排序:

      堆排序是不稳定的。可以把堆看成一棵完全二叉树,这棵完全二叉树满足:任何一个非叶子结点的值都不大于(或不小于)其左右孩子结点的值。若父亲大孩子节点,则这样的堆叫做大顶堆,反之叫小顶堆。

    对结点调整方法:
    1)  将当前结点(假设为a)的值与其孩子结点进行比较,如果存在大于a值的孩子结点,则从中选出最大的一个与a交换。当a来到下一层的时候重复以上过程,直到a的孩子结点值都小于a的值为止。

    2)  将当前无序序列中第一个元素,反映在树中是根结点(假设为a)与无序序列中最后一个元素交换(假设为b)。a进入有序序列,到达最终位置,无序序列中的元素减少1个,有序序列中元素增加1个。此时只有结点b可能不满足堆的定义,对其调整

    3)  重复2)过程,直到无序序列中的元素剩下1个时排序结束。

    适用范围:

    记录数很多的情况,典型的例子是从10000个记录中选出前10个最小的。

     

    时间复杂度

    空间复杂度

    稳定性

    最坏情况

    最好情况

    平均情况

    直接插入排序

    o(n2)

    o(n)

    o(n2)

    o(1)

    稳定

    折半插入排序

    o(n2)

    o(n)

    o(n2)

    o(1)

    稳定

    希尔排序

     

     

    O(nlog2n)

    o(1)

    不稳定

    冒泡排序

    o(n2)

    o(n)

    o(n2)

    o(1)

    稳定

    快速排序

    o(n2)

    o(nlog2n)

    o(nlog2n)

    o(log2n)

    不稳定

    简单选择排序

    o(n2)

    o(n2)

    o(n2)

    o(1)

    不稳定

    堆排序

     

     

    O(nlog2n)

    o(1)

    不稳定

    归并排序

    O(nlog2n)

    O(nlog2n)

    O(nlog2n)

    o(n)

     

  • 相关阅读:
    话说打工
    Linux系统信息查看命令大全
    基于LNMP的Zabbbix之Zabbix Server源码详细安装,但不给图
    基于LNMP的Zabbbix之PHP源码安装
    php --with-mysql=mysqlnd
    LeetCode:Binary Tree Level Order Traversal
    tslib-触摸屏校准
    A
    【雷电】源代码分析(二)-- 进入游戏攻击
    能够替代浮动的inline-block
  • 原文地址:https://www.cnblogs.com/lezhifang/p/6637029.html
Copyright © 2011-2022 走看看