zoukankan      html  css  js  c++  java
  • 算法排序2-基本排序方法2

    上一章

    5. 快速排序

    1. 快速排序是实现简单,使用于各种不同的输入数据且在一般应用中比其他排序算法都要快的多,
    2. 快速排序也是一种分治的排序算法,
    3. 在快速排序,,,你可以使用很多的辅助的方法,去实行快速排
      1. 原地切分
      2. 别越界
      3. 保持随机性
      4. 终止循环
      5. 处理切分元素值有重复的情况
      6. 终止递归
    4. 但是 如果主键是重复的项多的情况下,时间复杂度会是递增的
    5. 它将一个数组分成两个子数组,将两部分独立的排序,,在快速排序中,切分的位置取决于数组的内容
    
        public static void sort(Comparable[] a){
            StdRandom.shuffle(a);
    
            sort(a,0,a.length-1);
        }
    
    
        private static void sort(Comparable[] a, int lo,int hi){
            if (hi <= lo){
                return;
            }
            int j= partition(a,lo,hi);
            sort(a,lo,j-1);
            sort(a,j+1,hi);
        }
    
        private static int partition(Comparable[] a, int lo, int hi) {
            int i = lo , j = hi+1;
            Comparable v = a[lo];
            while (true){
                while (less(a[++i],v)){
                    if (i == hi){
                        break;
                    }
                }
                while (less(v,a[--j])){
                    if (j == lo){
                        break;
                    }
                }
                if (i >= j){
                    break;
                }
                exch(a,i,j);
            }
            exch(a,lo,j);
            return j;
        }
    
    
    1. 算法的改进
      1. 切换到插入排序
      2. 三取样切分
      3. 熵最优的排序
    // 三向区分的快速排序
    class Quick3way{
        private static void sort(Comparable[] a, int lo , int hi){
    
            if (hi <= lo){
                return;
            }
            int lt = lo,i=lo+1,gt = hi;
            Comparable v = a[lo];
            while (i <= gt){
                int cmp = a[i].compareTo(v);
                if (cmp <0){
                    exch(a,lt++,i++);
                }else if (cmp > 0){
                    exch(a,i,gt--);
                }else {
                    i++;
                }
            }
            sort(a,lo,lt-1);
            sort(a,gt+1,hi);
        }
    }
    
    

    6. 优先队列

    1. 不是每个程序,都需要排序整个数组,或许有那么多只需要查找最大的元素,,在这种的情况下,一个合适的数据结构应该支持 两种操作 : 删除最大元素和插入元素。
    2. 而优先队列最重要的操作就是***删除最大元素***和***插入元素***

    1. API

    1. 泛型优先队列的API -----MaxPQ

    2. 关联索引的泛型优先队列的API — IndexMinPQ

      1. 这个结构 可以能够快速访问其中最小元素的数组,
      2. 它能够快速访问数组的一个特定子集中的最小元素(指所有被插入的元素)

    2. 堆

    1. 堆的定义

    1. 数据结构二叉堆能够很好的实现优先队列的基本操作,

    2. 在二叉堆的数组中,每个元素都要保证大于等于另两个特定位置的元素

    3. 当一颗二叉树的每个结点都大于等于它的两个子结点,可说这个堆有序

    2. 一些特殊的代码实现

    1. 基于堆的优先队列

      package com.sort.priority.queue;
      
      /**
       * Created by IntelliJ IDEA.
       *
       * @version : 1.0
       * @auther : Firewine
       * @mail : 1451661318@qq.com
       * @Program Name: MaxPQ .java
       * @Create : 2019-02-25-19:21
       * @Description :  基于堆的优先队列
       */
      public class MaxPQ<key extends Comparable<key>> {
      
          private key[] pq;
          private int N = 0;
      
          public MaxPQ(int maxN){
              pq = (key[]) new Comparable[maxN +1];
          }
          public boolean isEmpty(){
              return N == 0;
          }
          public int size(){
              return N;
          }
          public void insert(key v){
              pq[++N] =v;
              swim(N);
          }
          public key delMax(){
              key max = pq[1];
              exch(1, N--);
              pq[N+1] = null;
              sink(1);
              return max;
          }
          private boolean less(int i,int j){
              return pq[i].compareTo(pq[j] ) < 0;
          }
      
          private void exch(int i,int j){
              key t = pq[i];
              pq[i] = pq[j];
              pq[j] = t;
          }
      
          /**
           * 由下至上的堆有序化
           * @param k
           */
          private void swim(int k){
              while (k>1 && less(k/2,k)){
                  exch(k/2,k);
              }
          }
      
          /**
           * 由上之下的堆有序化
           * @param k
           */
          private void sink(int k){
              while (2*k <= N){
                  int j = 2*k;
                  if (j < N && less(j,j+1)){
                      j++;
                  }
                  if (!less(k,j)){
                      break;
                  }
                  exch(k,j);
                  k = j;
              }
          }
      }
      
      
      1. 索引优先队列用例 —使用优先队列的多项归并

        package com.sort.priority.queue;
        
        
        import edu.princeton.cs.algs4.In;
        import edu.princeton.cs.algs4.IndexMinPQ;
        import edu.princeton.cs.algs4.StdOut;
        
        /**
         * Created by IntelliJ IDEA.
         *
         * @version : 1.0
         * @auther : Firewine
         * @mail : 1451661318@qq.com
         * @Program Name: Multiway .java
         * @Create : 2019-02-25-19:35
         * @Description :
         */
        public class Multiway {
        
            public static void merge(In[] streams) {
        
                int N = streams.length;
                IndexMinPQ<String> pq = new IndexMinPQ<>(N);
        
                for (int i = 0; i < N; i++) {
                    if (!streams[i].isEmpty()) {
                        pq.insert(i, streams[i].readString());
                    }
                }
                while (!pq.isEmpty()) {
                    StdOut.println(pq.delMin());
                    int i = pq.delMin();
                    if (!streams[i].isEmpty()) {
                        pq.insert(i, streams[i].readString());
                    }
                }
            }
        
            public static void main(String[] args) {
                
                int N = args.length;
                In[] streams = new In[N];
                for (int i=0;i<N;i++){
                    streams[i] = new In(args[i]);
                }
                merge(streams);
            }
        }
        
        
  • 相关阅读:
    webrtc系列之-像老鼠一样打洞
    Ubuntu记录用户IP访问操作信息工具
    OPENVIDU实现同一用户同时发布多个流媒体
    如何使用Nginx-rtmp搭建简易的HLS直播系统
    python实现数据库主从状态监控
    简单分析实现运维利器---批量操作bashshell
    《我与Windows Server 2008R2那点事儿》之域控账户故障事件
    常用动态路由协议之IS-IS
    在云服务器上搭建Python开发环境
    基于Python3接口自动化测试开发相关常用方法
  • 原文地址:https://www.cnblogs.com/YJBlog/p/10440693.html
Copyright © 2011-2022 走看看