排序专项——Java实现

1.Bubble Sort

遍历 ( n − 1 ) (n-1) (n1) 次要排序的数列,每次遍历时,它都会从前往后依次的比较相邻两个数的大小;如果前者比后者大,则交换它们的位置。一次遍历之后,最大的元素在数列的末尾。
采用相同的方法再次遍历时,第二大的元素就被排列在最大元素之前。
重复此操作,直到整个数列都有序为止

public class Main{

    public static void BubbleSort(int[] arr, int n){
        boolean change = false;
        int mid = 0;
        for(int i=n-1; i>0; i--){
            change = false;
            for(int j=0; j<i; j++){
                if(arr[j] > arr[j+1]){
                    change = true;
                    mid = arr[j+1];
                    arr[j+1] = arr[j];
                    arr[j] = mid;
                }
            }
            if(!change){
                break;
            }
        }
    }
    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0};
        BubbleSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }
    }
}

2.Quick Sort

随便在序列中选择一个数最为基准,将大于该数的放到右边,小于该数的放到左边,并将该数放到中间,再递归的以同样的方法排两边的数。

public class Main{

    public static void QuickSort(int[] arr, int l, int r){

        if(l >= r){
            return;
        }

        int mid = arr[l];
        int cur_l = l;
        int cur_r = r;

        while(cur_l < cur_r){
            //from right to find the first number smaller than 'mid'
            while(cur_l < cur_r && arr[cur_r] >= mid){
                cur_r--;
            }
            if(cur_l < cur_r){
                arr[cur_l] = arr[cur_r];
            }

            //from left to find the first number bigger than 'mid'
            while(cur_l < cur_r && arr[cur_l] <= mid){
                cur_l++;
            }
            if(cur_l < cur_r){
                arr[cur_r] = arr[cur_l];
            }
        }
        arr[cur_l] = mid;
        QuickSort(arr, l, cur_l-1);
        QuickSort(arr, cur_l+1, r);
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0};
        QuickSort(arr, 0 ,arr.length-1);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }
    }
}

3.Straight Insertion Sort

数组前半部分是排好的有序数组,数组后半部分是待排数组。
每次从后边的待排数组中拿出一个插入到前边有序数组中的正确位置。


public class Main{

    public static void InsertSort(int[] arr, int n){
        for(int i=0; i<n; i++){
            int index = i-1;
            int cur = arr[i];
            while(index >= 0 && arr[index] > cur){
                arr[index+1] = arr[index];
                index--;
            }
            arr[index+1] = cur;
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        InsertSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }
    }
}

4.Shell Sort

希尔排序是改进的插入排序,之前插入排序是将整个数列看成一个整体,而这样数据量过大时,耗时较长,故采用分组策略,每次指定一个步长,根据步长进行分组,并把每个分组进行插入排序,并逐步缩短步长,直到最后步长为0,即可实现整个序列有序。

public class Main{

    public static void ShellSort(int[] arr, int n){
        for(int gap=n/2; gap>=1; gap/=2){
            for(int i=0; i<gap; i++){
                InsertSort(arr, n, i, gap);
            }
        }
    }

    public static void InsertSort(int[] arr, int n, int start, int gap){
        for(int i=start; i<n; i+=gap){
            int index = i-gap;
            int cur = arr[i];
            while(index >= 0 && arr[index] > cur){
                arr[index+gap] = arr[index];
                index-=gap;
            }
            arr[index+gap] = cur;
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        ShellSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }
    }
}

5.Selection sort

  • 在未排序的数列中找到最小(最大)元素,然后将其存放到数列的起始位置
  • 从剩余未排序的元素中继续寻找最小(最大)元素,然后放到已排序序列的末尾
  • 以此类推,直到所有元素均排序完毕。
public class Main{

    public static void SelectSort(int[] arr, int n){
        int min_index;
        for(int i=0; i<n; i++){

            //find the smallest in [i, n]
            min_index = i;
            for(int j=i+1; j<n; j++){
                if(arr[j] < arr[min_index]){
                    min_index = j;
                }
            }

            //make the smallest to [i]
            int change = arr[min_index];
            arr[min_index] = arr[i];
            arr[i] = change;
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        SelectSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }
    }
}

6.Heap Sort

对于堆排序,Java Collection 中有个 PriorityQueue 优先队列, 可以快速实现堆排序

//在类似csp这种没有实时反馈的比赛中,尽量使用不抛出异常的语句,否则就直接爆0
      PriorityQueue<Integer> pq = new PriorityQueue<>();
      for(int i=0; i<10; i++){
          pq.offer(10-i);
      }
      while(!pq.isEmpty()){
          System.out.printf("%d ", pq.peek());
          pq.poll();
      }

手写二叉树维护堆。(数组实现)

public class Main{

    public static void ChangeDown(int[] arr, int index, int n){
        int child = index*2 + 1;

        while(child < n){
            //find the biggest child
            if(child < n-1 && arr[child] < arr[child+1]){
                child++;
            }
            if(arr[index] >= arr[child]){
                break;
            }else{
                int mid = arr[index];
                arr[index] = arr[child];
                arr[child] = mid;
            }

            index = child;
            child = index * 2 + 1;
        }
    }

    public static void HeapSort(int[] arr, int n){
        //construct maxheap
        for(int i=(n-1)/2; i>=0; i--){
            ChangeDown(arr, i, n);
        }
        //sort the array
        for(int i=n-1; i>=0; i--){
            int mid = arr[0];
            arr[0] = arr[i];
            arr[i] = mid;
            ChangeDown(arr, 0, i);
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        HeapSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }

    }
}

7.Merge Sort

归并排序可以配合多线程加快速度。

自顶向下进行归并排序
图片来自 http://wangkuiwu.github.io/media/pic/datastruct_algrithm/algrithm/merge_01.jpg
在这里插入图片描述

public class Main{

    public static void merge(int[] arr, int start, int mid, int end){
        int[] result = new int[end-start+1];
        int cur1 = start;
        int cur2 = mid+1;
        int index = 0;
        while(cur1 <=mid && cur2 <=end){
            if(arr[cur1] > arr[cur2]){
                result[index++] = arr[cur2];
                cur2++;
            }else{
                result[index++] = arr[cur1];
                cur1++;
            }
        }

        while(cur1 <= mid){
            result[index++] = arr[cur1++];
        }
        while(cur2 <= end){
            result[index++] = arr[cur2++];
        }

        for(int i=0; i<end-start+1; i++){
            arr[start+i] = result[i];
        }
    }

    public static void MergeSort(int[] arr,int start, int end){
        if(start >= end){
            return;
        }

        int mid = start + (end - start)/2;
        //divide into two array
        MergeSort(arr, start, mid);
        MergeSort(arr, mid+1, end);
		//merge two array
        merge(arr, start, mid, end);
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        MergeSort(arr, 0, arr.length-1);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }

    }
}

8.Bucket Sort

桶排序用一个数组的下标代表值,每存在一个值,就将对于下标的值加1,最后从头将数组扫描一遍即可

import java.util.Arrays;

public class Main{

    public static void BucketSort(int[] arr, int n, int maxx){
        int[] bucket = new int[maxx];
        Arrays.fill(bucket, 0);
        for(int i=0; i<n; i++){
            bucket[arr[i]]++;
        }

        int index = 0;
        for(int i=0; i<maxx; i++){
            while(bucket[i]>0){
                arr[index++] = i;
                bucket[i]--;
            }
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,3,4,5,6,0,3};
        BucketSort(arr, arr.length, 20);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }

    }
}

9.Radix Sort

作为桶排序的拓展,将整数按位数切割成不同的数字,然后按每个位数分别比较。

import java.util.Arrays;

public class Main{

    public static void BubbleSort(int[] arr, int n, int exp){
        int[] bubble = new int[10];
        int[] result = new int[n];
        Arrays.fill(bubble, 0);

        for(int i=0; i<n; i++){
            bubble[(arr[i]/exp)%10]++;
        }
        for(int i=1; i<n; i++){
            bubble[i] = bubble[i] + bubble[i-1];
        }

        for(int i=0; i<n; i++){
            result[bubble[(arr[i]/exp)%10]-1] = arr[i];
            bubble[(arr[i]/exp)%10]--;
        }

        for(int i=0; i<n ;i++){
            arr[i] = result[i];
        }
    }

    public static void RadixSort(int[] arr, int n){
        int maxx = arr[0];
        for(int i=1; i<n; i++){
            if(arr[i] > maxx){
                maxx = arr[i];
            }
        }

        for(int i=1; maxx/i>0; i*=10){
            BubbleSort(arr, n, i);
        }
    }

    public static void main(String[] args) {
        int[] arr  = {1,2,200,3,4,5,6,0,3};
        RadixSort(arr, arr.length);
        for(int xx: arr){
            System.out.printf("%d ", xx);
        }

    }
}

总结

在这里插入图片描述
图片来源https://www.cnblogs.com/onepixel/articles/7674659.html

参考博客:

  1. http://wangkuiwu.github.io
  2. https://www.cnblogs.com/onepixel/articles/7674659.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值