zoukankan      html  css  js  c++  java
  • 快速、归并和基数排序

    快速排序

    public class QuickSort {
        /*
        快速排序由C. A. R. Hoare在1960年提出。
        它的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据
        都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个
        排序过程可以递归进行,以此达到整个数据变成有序序列。
        (冒泡排序的改进)
         */
        public static  void quickSort(int[]arr,int left,int right){
            int l = left;
            int r = right;
            int pivot = arr[(left+right)/2];
            int temp=0;
            while (l<r){
                while (arr[l]<pivot){
                    l+=1;
                }
                while (arr[r]>pivot){
                    r-=1;
                }
                if(l>=r){
                    break;
                }
                temp=arr[l];
                arr[l]=arr[r];
                arr[r]=temp;
                if(arr[l]==pivot){
                    r-=1;
                }
                if(arr[r]==pivot){
                    l+=1;
                }
                if(l==r){
                    l+=1;
                    r-=1;
                }
                if(left<r){
                    quickSort(arr,left,r);
                }
                if(right>l){
                    quickSort(arr,l,right);
                }
            }
        }
    }

    归并排序

    public class MergeSort {
    
        /*
        归并排序(Merge Sort)是建立在归并操作上的一种有效,稳定的排序算法,该算法是采用分治法
        (Divide and Conquer)的一个非常典型的应用。将已有序的子序列合并,得到完全有序的序列;
        即先使每个子序列有序,再使子序列段间有序。若将两个有序表合并成一个有序表,称为二路归并。
         */
        public static void mergeSort(int[] arr,int left,int right,int[] temp) {
            if(left<right){
                int mid = (left+right)/2;
                mergeSort(arr,left,mid,temp);//向左递归
                mergeSort(arr,mid+1,right,temp);//向右递归
                //以上是将数组分解
                merge(arr,left,mid,right,temp);
                //每一次分解都进行一次合并,因为方法由栈内存保存,所以必然先合并原子,最后将两个数组合并为一个
            }
        }
    
        /**
         * 为了将分开的每一组按顺序合并
         * @param arr 将要处理的数组
         * @param left  左索引
         * @param mid  中间索引
         * @param right 右索引
         * @param temp  临时数组
         */
        private static void merge(int[] arr,int left,int mid,int right,int[] temp) {
            int l = left;
            int j = mid+1;
            int t = 0;
            //将左右两边的数字,规则填充到temp数组,直到有一边填充完毕为止
            while(l<=mid && j<=right){
                if(arr[l]<=arr[j]){
                   temp[t]=arr[l];
                   t+=1;
                   l+=1;
                }else{
                    temp[t]=arr[j];
                    t+=1;
                    j+=1;
                }
            }
            //将剩余的数字填充到temp数组
            while(l<=mid){
                temp[t]=arr[l];
                t+=1;
                l+=1;
            }
            while(j<=right){
                temp[t]=arr[j];
                t+=1;
                j+=1;
            }
    
            //将临时数组的元素拷贝到temp
            t=0;
            int tempLeft = left;
            while(tempLeft<=right){
                arr[tempLeft]=temp[t];
                t+=1;
                tempLeft+=1;
            }
        }
    
    }

    基数排序

    public class RadixSort {
        /*
        1.属于“分配性排序”,通过键值的各个位的值将要排序的元素分配到桶中
        2.将整数按位数切割为不同的数字,然后按每个位数分别比较
         */
        public static void radixSort(int[] arr) {
            //找到最大的数,并得到其位数
            int max=arr[0];
            for(int i=1;i<arr.length;i++){
                if(arr[i]>max){
                    max=arr[i];
                }
            }
            int maxlength =( max+"").length();
            //定义10个桶,每个通最多可以装和原数组相同的个数
            int[][] bucket = new int[10][arr.length];
            //记录每个桶中的原数个数,如bucketElementsCounts[0]记录1号桶中的数
            //相应位数是几就放到几号桶中,比如十位数是0在第二轮就放到0号桶中
            int[]  bucketElementsCounts=new int[10];
            //每一轮都按设定的顺序将元素放入对应的桶中,直到完成最后一轮
            int index;
            for (int i = 0,n=1; i < maxlength; i++,n*=10) {
                for (int j = 0; j < arr.length; j++) {
                    int digitOfElement = arr[j] / n % 10;//用来记录位数
                    bucket[digitOfElement][bucketElementsCounts[digitOfElement]] = arr[j];
                    bucketElementsCounts[digitOfElement]++;
                }
                //将桶中的数据放入到原数组中
                index = 0;
                for (int k = 0; k < bucketElementsCounts.length; k++) {
                    if (bucketElementsCounts[k] != 0) {
                        for (int l = 0; l < bucketElementsCounts[k]; l++) {
                            arr[index++] = bucket[k][l];
                        }
                    }
                    bucketElementsCounts[k]=0;//将桶中的数据归0
                }
            }
        }
    }
  • 相关阅读:
    温故而知新--JavaScript书摘(二)
    WebSocket 浅析
    温故而知新--JavaScript书摘(一)
    HTTP2.0 简明笔记
    XHR简介
    HTTP 1.1学习笔记
    选择一个 HTTP 状态码不再是一件难事 – Racksburg《转载》
    Buffer学习笔记.
    浏览器的userAgent归纳
    Ngnix日志分析
  • 原文地址:https://www.cnblogs.com/susexuexi011/p/14209988.html
Copyright © 2011-2022 走看看