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 
    
  • 相关阅读:
    【原创】(四)Linux进程调度-组调度及带宽控制
    【原创】(三)Linux进程调度器-进程切换
    【原创】(一)Linux进程调度器-基础
    【原创】(十六)Linux内存管理之CMA
    【原创】(十五)Linux内存管理之RMAP
    【原创】(十四)Linux内存管理之page fault处理
    我是如何学习和工作的(3)
    亲人的离去、爱情与婚姻
    工作机会少有时反而是一件好事
    Hong Kong Azure / .NET club first meetup
  • 原文地址:https://www.cnblogs.com/lillcol/p/11171994.html
Copyright © 2011-2022 走看看