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

    我们通常所说的排序算法往往指的是内部排序算法,即数据记录在内存中进行排序。排序算法大体可分为两种:一种是比较排序,时间复杂度O(nlogn) ~ O(n^2),主要有:冒泡排序选择排序插入排序归并排序堆排序快速排序等。另一种是非比较排序,时间复杂度可以达到O(n),主要有:计数排序基数排序桶排序等。

     算法复杂度

     冒泡排序

    一组无序的数据arr[0]、arr[1]、……arr[n],按升序排列,首先比较a[0]与a[1]的值,若a[0]大于a[1]则交换两者的值,否则不变。再比较a[1]与a[2]的值,若a[1]大于a[2]则交换两者的值,否则不变。再比较a[2]与a[3],以此类推,最后比较a[n-1]与a[n]的值。这样处理一轮后,a[n]的值一定是这组数据中最大的。用相同的方法对a[0]~a[n-1]以相同处理一轮,则a[n-1]的值一定是a[0]~a[n-1]中最大的。以此循环,最后比较a[0]和a[1]位置的两个值,若a[0]大于a[1]则交换位置,否则不变。理论上总共要进行n(n-1)/2次交换。代码实现如下:

     public static void bubbleSort(int[] arr) {
            for (int i = 1; i < arr.length; i++) {
                for (int j = 0; j < arr.length - i; j++) {
                    if (arr[j] > arr[j + 1]) {
                        int temp = arr[j];
                        arr[j] = arr[j + 1];
                        arr[j + 1] = temp;
                    }
                }
            }
        }

    选择排序

    选择排序的工作原理:初始时在序列中找到最小(大)元素,放到序列的起始位置作为已排序序列;然后,再从剩余未排序元素中继续寻找最小(大)元素,放到已排序序列的末尾。以此类推,直到所有元素均排序完毕。代码实现如下:

        public static void selectSort(int[] arr) {
            for(int i = 0; i < arr.length; i++) {
                int k = i;
                for(int j = arr.length-1; j > i; j --) {
                    if(arr[j] < arr[k]) {
                        k = j;
                    }
                }
                int temp = arr[i];
                arr[i] = arr[k];
                arr[k] = temp;
            }
            System.out.println(Arrays.toString(arr));
        }

    插入排序

    插入排序的工作原理:每步将一个待排序的记录,按其顺序码大小插入到前面已经排序的字序列的合适位置(从后向前找到合适位置后),直到全部插入排序完为止。

        public static void inserSort (int[] arr) {
            int j = 0;
            for(int i = 0; i < arr.length; i ++) {
                int temp = arr[i];
                for( j = i; j> 0 && temp < arr[j-1];j--) {
                    arr[j] = arr[j-1];
                }
                arr[j] = temp;
            }
        }

    归并排序

    归并排序的工作原理:通过将数组不断地二分,直到最后每个部分只包含 1 个数据。然后再对每个部分分别进行排序,最后将排序好的相邻的两部分合并在一起,这样整个数组就有序了。

     public static void customMergeSort(int[] a, int[] tmp, int start,int end){
            if(start < end) {
                int mid = (start+end)/2;
                customMergeSort(a,tmp,start,mid);
                customMergeSort(a,tmp,mid+1,end);
                customDoubleMerge(a,tmp,start,mid,end);
            }
         }
    
        public static void  customDoubleMerge(int[] a, int[] tmp, int left,int mid,int right){
            int p1 = left, p2= mid+1, k = left;
            while(p1 <= mid && p2 <= right) {
                if (a[p1] <= a[p2]) {
                    tmp[k++] = a[p1++];
                } else {
                    tmp[k++] = a[p2++];
                }
            }
            while(p1 <= mid){
                tmp[k++] = a[p1++];
            }
            while(p2 <= right){
                tmp[k++] = a[p2++];
            }
            for(int i = left; i <= right; i++) {
                a[i] = tmp[i];
            }
        }

    快速排序

    快速排序的工作原理:通过一趟排序将待排序记录分割成独立的两部分,其中一部分记录的关键字均比另一部分关键字小,则分别对这两部分继续进行排序,直到整个序列有序。

        public static int partition(int[] a, int low, int high) {
            int pivotkey = a[low];  //数组的第一个作为中轴
            while (low < high) {
                while (low < high && a[high] >= pivotkey)
                    --high;
                a[low] = a[high];    //比中轴小的记录移到低端
                while (low < high && a[low] <= pivotkey)
                    ++low;
                a[high] = a[low];   //比中轴大的记录移到高端
            }
            a[low] = pivotkey;  //中轴记录到尾
            return low;     // 返回中轴的位置
        }
    
        /**
         * @param arr 带排序数组
         * @param low     开始位置
         * @param high    结束位置
         */
        public static void quickSort(int[] arr, int low, int high) {
            if (low < high) {
                int middle = partition(arr, low, high); //将arr数组进行一分为二
                quickSort(arr, low, middle - 1);   //对低字段表进行递归排序
                quickSort(arr, middle + 1, high); //对高字段表进行递归排序
            }
    
        }
  • 相关阅读:
    初见QT---信号和槽(二)
    初见QT---信号和槽
    Python的那些事---数据分析(一)---NumPy基础
    初见QT---创建QPushButton按钮
    初见QT---QT creator常见快捷键使用
    PHP 反射 Reflection
    python 代码求阶乘
    Python中的计时器对象
    python websocket 再线聊天室的 Demo
    Tornado创建一个web服务
  • 原文地址:https://www.cnblogs.com/loytime/p/9972293.html
Copyright © 2011-2022 走看看