排序算法笔记

2018-03-21  本文已影响0人  Xun_Moo

总结

排序算法.png

算法详解

tips:以下算法中均按从小到大排序

一 冒泡排序/Bubble Sort

思路

采用两两比较并交换位置的思路,就仿佛泡泡一样,较大的元素会慢慢“上浮”

复杂度

代码实现

public static void sort(int[] numbers) {
        for (int i = 0; i < numbers.length; i++) {
            for (int j = 0; j < numbers.length-i-1; j++) {
                if (numbers[j]> numbers[j+1]){//大数在前则交换位置
                    int temp = numbers[j+1];
                    numbers[j+1] = numbers[j];
                    numbers[j] = temp;
                }
            }
        for (int num: numbers) {
            System.out.println(num);
        }
     }
 }

二 快速排序/Quick Sort

思路

复杂度

代码实现

public static void sort(int[] numbers,int left,int right){
        if(left>=right){
            return;
        }
        int tag = numbers[left];
        int lo = left;
        int hi = right;
        while (left<right){
            while ((tag<=numbers[right])&&(left<right)){
                right--;
            }
            numbers[left] = numbers[right];
            while ((tag>=numbers[left])&&(left<right)){
                left++;
            }
            numbers[right] = numbers[left];
        }
        numbers[left] = tag;
        sort(numbers,lo,left-1);
        sort(numbers,left+1,hi);
    }

三 插入排序/Insert Sort

思路

复杂度

代码实现

public static void sort(int[] numbers){
        int pre;
        int current;
        for (int i = 1; i < numbers.length ; i++) {//假定第一位已经排序,所以从number[1]开始,
            pre = i - 1;
            current = numbers[i];//记录待排序的数值
            while ((pre>=0)&&(numbers[pre]>=current)){
                numbers[pre+1] = numbers[pre];//将大于等于current的值往后挪一位
                pre--;
            }
            numbers[pre+1] = current;
        }
  }

四 希尔排序/Shell Sort

希尔排序也被称为“缩小增量排序”

思路

复杂度

代码实现

public static void sort(int[] numbers){
        int div = numbers.length/2;//取第一个间隔
        while (div>0){
            for (int i = div; i < numbers.length ; i++) {//对每个区间做插入排序
                int current = numbers[i];
                int preindex = i-div;
                while ((preindex>=0)&&(numbers[preindex]>current)){
                    numbers[preindex+div] = numbers[preindex];
                    preindex -= div;
                }
                numbers[preindex+div] = current;
            }
            div = div/2;
        }
 }

五 选择排序/Select Sort

思路

复杂度

代码实现

public static void sort(int[] numbers){
        int index = 0;
        while (index < numbers.length-1){
            int temp = numbers[index];
            int current = index+1;
            for (int i = index+1; i < numbers.length; i++) {//查找未排序数列中的最小值
                if(temp>numbers[i]){
                    temp = numbers[i];
                    current = i;
                }
            }
            //交换。将最小值放到未排序数列最前面
            numbers[current] = numbers[index];
            numbers[index] = temp;
            index++;
        }
 }

六 堆排序/Heap Sort

思路

复杂度

代码实现

public static void sort(int[] numbers){
        int length = numbers.length;
       //从后往前,构建最大堆
        for (int i = length/2; i >=0 ; i--) {
            toMaxHeap(numbers,i,length);
        }
        while (length>0){
            //最大值移入有序区
            int temp = numbers[0];
            numbers[0] = numbers[length-1];
            numbers[length-1] = temp;
            length--;
            toMaxHeap(numbers,0,length);
        }
    }
    /**
     * 将无序区调整为最大堆的方法
     */
    public static void toMaxHeap(int[] numbers, int index, int length){
        int left = index*2+1;
        int right = index*+2;
        int max_index = index;
        if((left<length)&&(right<length)&&numbers[left]>numbers[right]){
            max_index = left;
        }else if((left<length)&&(right<length)&&numbers[left]<=numbers[right]){
            max_index = right;
        }
        if(numbers[index]<numbers[max_index]){//不是最大堆,则调整一下
            int temp = numbers[max_index];
            numbers[max_index] = numbers[index];
            numbers[index] = temp;
            toMaxHeap(numbers,max_index,length);
        }
}

七 归并排序/Merge Sort

思路

复杂度

代码实现

public static void sort(int[] numbers, int begin, int end){
        int mid = (begin+end)/2;
        if(begin<end){
            sort(numbers,begin,mid);//对左边进行排序
            sort(numbers,mid+1,end);//对右边进行排序
            merge(numbers,begin,mid,end);
        }
    }
    public static void merge(int[] number, int low, int mid, int high){
        int[] container = new int[high-low+1];//开辟临时存储区
        int i = low;//第一个数组的起点
        int j = mid+1;//第二个数组的起点
        int index = 0;//临时存储区的下标
        while ((i<=mid)&&(j<=high)){
            //依次将较小的数放入container
            if(number[i]<number[j]){
                container[index] = number[i];
                i++;
            }else {
                container[index] = number[j];
                j++;
            }
            index++;
        }
        while (i<=mid){
            container[index] = number[i];
            i++;
            index++;
        }
        while (j<=high){
            container[index] = number[j];
            j++;
            index++;
        }
        for (int k = 0; k < container.length; k++) {
            number[low+k] = container[k];
        }
    }

计数排序/Counting Sort

思路

非比较排序,待排序的数列需要是有限范围内的整数

复杂度

代码实现

public static void sort(int[] numbers){
        int large = numbers[0];
        int little = numbers[0];
        //最大最小
        for (int num:numbers) {
            if(num>large){
                large = num;
            }else if(num<little){
                little = num;
            }
        }
        int[] count = new int[large+1];
        for (int num:numbers) {
            count[num]++;
        }
        int index = 0;
        for (int i = little; i < count.length; i++) {
            while (count[i]>0){
                numbers[index++] = i;
                count[i]--;
            }
        }
    }

桶排序/Bucket Sort

思路

是对计数排序的改进。将数列按照一定的映射关系划分为大小相同的子区间,区间内元素排序,然后合并

复杂度

代码实现

public static void sort(int[] numbers){
        int large = numbers[0];
        int little = numbers[0];
        //最大最小
        for (int num:numbers) {
            if(num>large){
                large = num;
            }else if(num<little){
                little = num;
            }
        }
        int bucketSize = numbers.length;//如果数据均匀的话,桶的大小不需要为数列的大小
        int bucketNum = (large - little) / bucketSize + 1;
        ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(bucketNum);
        for(int i = 0; i < bucketNum; i++){
            buckets.add(new ArrayList<Integer>());
        }
        //将每个元素放入桶
        for(int i = 0; i < numbers.length; i++){
            int index = (numbers[i] - little) / bucketSize;
            buckets.get(index).add(numbers[i]);
        }
        //对每个桶进行排序
        for(int i = 0; i < buckets.size(); i++){
            Collections.sort(buckets.get(i));
        }
        int index = 0;
        for (ArrayList<Integer> list:buckets) {
            for (Integer i: list) {
                numbers[index] = i;
                index++;
            }
        }

    }

基数排序/Radix Sort

思路

复杂度

代码实现

public static void sort(int[] numbers) {//默认10进制
        int large = numbers[0];
        //最大数
        for (int num : numbers) {
            if (num > large) {
                large = num;
            }
        }
        int digit = String.valueOf(large).length();//最大位数
        int mod = 10;
        int dev = 1;
        int bucketNum = 10;
        ArrayList<ArrayList<Integer>> buckets = new ArrayList<>(bucketNum);
        for (int i = 0; i < bucketNum; i++) {
            buckets.add(new ArrayList<Integer>());
        }
        for (int i = 0; i < digit; i++, dev *= 10, mod *= 10) {
            for (int j = 0; j < numbers.length; j++) {
                int bucket = (int) ((numbers[j] % mod) / dev);
                buckets.get(bucket).add(numbers[j]);
            }
            int index = 0;
            for (int k = 0; k < bucketNum; k++) {
                ArrayList<Integer> list = buckets.get(k);
                if (list.size()>0) {
                    for (Integer num:buckets.get(k)) {
                        numbers[index++] = num;
                    }
                    list.clear();//将桶清空
                }
            }
        }
    }
上一篇 下一篇

猜你喜欢

热点阅读