zoukankan      html  css  js  c++  java
  • 常见排序算法

    定义

    假设含有n个记录的序列为{r1​,r2​,…,rn​},其相应的关键字分别为{k1​,k2​,…,kn​},需确定1,2, 3, …, n的一种排列p1​,p2​,…,pn​,使其相应的关键字满足kp1​ ≤kp2​≤…≤kpn​非递减(或非递增)关系,即使得序列变成一个按关键字有序的序列{rp1​,rp2​,…,rpn​}

    让[1, 2, 32, 23, 321, 45, 8, 90, 227, 99]从小到大排列

    常见排序

    • 冒泡排序
      先拿第1第2个数比较,谁大谁后面,接着第2个跟第3个,继续...,最后的那个数一定是最大的。接下来混乱的序列就少了一位,继续剩下的序列继续上面的一轮。这个过程就像一个波浪一次把最大值从前面推到后面
    public static void main(String[] args) {
            // TODO Auto-generated method stub
            int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99};
            for(int i=0;i<arr.length-1;i++) {
                for(int j=0;j<arr.length-i-1;j++) {
                    if(arr[j]>arr[j+1]) {
                        int temp=arr[j];
                        arr[j]=arr[j+1];
                        arr[j+1]=temp;
                    }
                }
            }
            for(int a:arr) {
                System.out.print(a+" ");
            }
        }
        
        //1 2 8 23 32 45 90 99 227 321 
    
    • 选择排序
      冒泡排序每次比较后符合要求的都去交换,有些处于中间值的,不是要不断的被交换,不是很浪费时间?能不能选出这段序列中最大的那个数,然后放到最后边? 这就是选择排序。
    public static void main(String[] args) {
            int []arr= {1, 2, 32, 23, 321, 45, 8, 90, 227, 99};
            for(int i=0;i<arr.length-1;i++) {
                int k=i;
                //位置还不确定的数据
                for(int j=i+1;j<arr.length;j++) {
                    if(arr[j]<arr[k]) {
                        k=j;
                        //遍历找到比k小的索引,然后把j赋给k;
                    }
                }
                if(i!=k) {
                    int temp=arr[i];
                    arr[i]=arr[k];
                    arr[k]=temp;
                }
            }
            for(int a:arr) {
                System.out.print(a+" ");
            }
        }
        //1 2 8 23 32 45 90 99 227 321 
    
    • 插入排序
      举个例子,假设现在桌面有几张牌,每次拿起一张,我们在排序的时候会很自然的将牌按照顺序插入合适的位置。这个思想就是插入排序。
      public static void insertSort(int[] arr) {
            int j = 0;
            for (int i = 1; i < arr.length; i++) {
                int temp = arr[i];//要插入的值,i位置空出来了
                for (j = i; j > 0 && arr[j - 1] > temp; j--) {
                    arr[j] = arr[j - 1];//j-1 扔到空出来的位置
                }
                arr[j] = temp;//temp 扔到空出来的位置
            }
        }
         //1 2 8 23 32 45 90 99 227 321 
    
    • 希尔排序
      希尔排序排序是插入排序的改进算法,实现原理是将整个无序列分割成若干小的子序列分别进行插入排序,希尔排序并不稳定。该方法又称缩小增量排序。
     public static void shellSort(int[] a) {
            int dk;//步长
            for (dk = a.length / 2; dk > 0; dk /= 2) {
                for (int i = dk; i < a.length; i++) {
                    int temp = a[i];//要插入的值,i位置空出来了
                    int j;
                    for (j = i; j >= dk && temp < a[j - dk]; j -= dk)//步长为dk的插入排序
                        a[i] = a[j - dk]; //j - dk 扔到空出来的位置
                    a[j] = temp;//temp 扔到空出来的位置
                }
            }
        }
        //1 2 8 23 32 45 90 99 227 321 
    
    • 归并排序
      将带排序序列分成小组,每个小组自己先弄成有序的,再汇总,这样这种分而治之思想的实际上就是归并排序。
        public static void mergerSort(int arr[], int low, int high) {
            int mid = (low + high) >> 1;
            if (low < high) {
                mergerSort(arr, low, mid);
                mergerSort(arr, mid + 1, high);
                merger(arr, low, mid, high);
            }
    
        }
    
        public static void merger(int arr[], int low, int mid, int high) {
            int temp[] = new int[high - low + 1]; //临时数组
            int t = 0;//临时数组的首索引
            int first = low;//第一个数组的首索引
            int second = mid + 1;//第二个数组的首索引
    
            // 将练个有序数组比较插入临时数组
            while (first <= mid && second <= high) {
                temp[t++] = arr[first] < arr[second] ? arr[first++] : arr[second++];
            }
    
            //  将数组剩余部分接到临时数组尾部
            while (first <= mid) {
                temp[t++] = arr[first++];
            }
            while (second <= high) {
                temp[t++] = arr[second++];
            }
    
            //    将临时数据合并到原始数组
            for (int i = 0; i < temp.length; i++) {
                arr[i + low] = temp[i];
            }
        }
        //1 2 8 10 23 32 45 90 99 227 321 
    
    • 快速排序
      举个例子:上体育课的时候要高个子站后面矮个子站前面,教练没办法一开始就一眼看出谁高谁矮对,那么多人,肯定是随便逮一个逮个人,来以他为基准进行排序。要求小个子的站这人的前边,大个子的站后边。
      而这就是快速排序的核心思想。
     public static void quickSort(int arr[], int low, int high) {
            if (low < high) {
                int index = part(arr, low, high);
                quickSort(arr, low, index - 1);
                quickSort(arr, index + 1, high);
    
            }
        }
        
        public static int part(int arr[], int low, int high) {
            int s1=low,s2=high;//定义哨兵
            int key = arr[low];
            while (s1 < s2) {
                while (s1 < s2 && (arr[s2] >= key)) {//哨兵2 向左巡逻 查找小于key的位置 停下
                    s2--;
                }
                swap(arr,s1, s2);
                while (s1 < s2 && arr[s1] <= key) {//哨兵1 向右巡逻 查找大于key的位置  停下
                    s1++;
                }
                swap(arr, s1, s2);
            }
            return s1;
    
        }
    
        public static void swap(int arr[], int s1, int s2) {
    
            int temp = arr[s1];
            arr[s1] = arr[s2];
            arr[s2] = temp;
        }
    //1 2 2 6 8 10 23 32 45 90 99 321 
    
  • 相关阅读:
    ZOJ 1002 Fire Net
    Uva 12889 One-Two-Three
    URAL 1881 Long problem statement
    URAL 1880 Psych Up's Eigenvalues
    URAL 1877 Bicycle Codes
    URAL 1876 Centipede's Morning
    URAL 1873. GOV Chronicles
    Uva 839 Not so Mobile
    Uva 679 Dropping Balls
    An ac a day,keep wa away
  • 原文地址:https://www.cnblogs.com/lillcol/p/11171994.html
Copyright © 2011-2022 走看看