常见排序之Java实现

原创
2016/07/09 18:00
阅读数 213

主程序

public class Test {
    public static void main(String[] args) {
        int[] arrs = {1, 9, 4, 50, 63, 82, 37} ;
        System.out.println(Arrays.toString(arrs)) ;
        //mergeSort(arrs, 0, arrs.length-1) ;    
        //quickSort(arrs, 0, arrs.length - 1) ;
        heapSort(arrs) ;
        System.out.println(Arrays.toString(arrs)) ;
    }

}

交换数组中的两个元素

    private static void swap(int[] array, int low, int high) {
        int temp = array[low] ;
        array[low] = array[high] ;
        array[high] = temp ;
    }

插入排序

    public static void insertSort(int[] arr) {
        int key ;   //用于保存要插入的值
        for(int i=1 ; i<=arr.length-1 ; i++) {
            key = arr[i] ;
            for(int j=i-1 ; j>=0 ; j--) {
                if(key < arr[j]) {
                    arr[j+1]=arr[j] ;   //记录后移
                }
                else {
                    arr[j+1] = key ;    //找到插入的位置
                    break ;
                }
            }
        }
    }

选择排序(当前元素 VS 余下元素)

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

冒泡排序(两两比较)

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

二路归并排序(递归版本)

    public static void mergeSort(int[] arr, int low, int high) {
        if(low < high) {
            int mid = (low+high) / 2 ;
            mergeSort(arr, low, mid) ;
            mergeSort(arr, mid+1, high) ;
            merge(arr, low, mid, high) ;
        }
    }

    public static void merge(int[] arr, int left, int center, int right) {
        int[] temp = new int[right-left+1] ;    //归并排序的空间复杂度为O(n)
        int k = 0 ;
        int r1 = center+1 ;     //右边起始下标
        int start = left ;      //保存拷贝的起始位置

        while(left<=center && r1<=right) {
            if(arr[left] < arr[r1]) { temp[k++] = arr[left++] ; }
            else { temp[k++] = arr[r1++] ; }
        }

        //拷贝剩余元素
        while(left <= center) { temp[k++] = arr[left++] ; }
        while(r1 <= right) { temp[k++] = arr[r1++] ; }

        //将临时数组中的元素拷贝至原数组
        k = 0 ;
        for(int i=start; i<=right ; i++) { arr[i] = temp[k++] ; }
    }

二路归并排序(非递归版本)

    public static void mergeSort(int[] arr) {
        int length = arr.length ;
        int low, mid, high ;
        for(int step = 1 ; step <= length; step*=2) {   //step为步长
            low = 0 ;
            while(low+step <= length) {
                mid = low + step - 1 ;
                high = mid + step ;
                if(high >= length) { high = length - 1 ; }      //元素个数小于step
                merge(arr, low, mid, high);
                low = high + 1 ;    //下次归并的下界
            }
        }
    }

    public static void merge(int[] arr, int left, int center, int right) {
        int[] temp = new int[right-left+1] ;    //归并排序的空间复杂度为O(n)
        int k = 0 ;
        int r1 = center+1 ;     //右边起始下标
        int start = left ;      //保存拷贝的起始位置

        while(left<=center && r1<=right) {
            if(arr[left] < arr[r1]) { temp[k++] = arr[left++] ; }
            else { temp[k++] = arr[r1++] ; }
        }

        //拷贝剩余元素
        while(left <= center) { temp[k++] = arr[left++] ; }
        while(r1 <= right) { temp[k++] = arr[r1++] ; }

        //将临时数组中的元素拷贝至原数组
        k = 0 ;
        for(int i=start; i<=right ; i++) { arr[i] = temp[k++] ; }
    }

快速排序(递归版本)

    public static void quickSort(int[] array, int low, int high) {
        if(low < high) {
            int i = partition(array, low, high) ;
            quickSort(array, low, i-1);
            quickSort(array, i+1, high);
        }
    }

    private static int partition(int[] array, int low, int high) {
        int pivot = array[low] ;

        while(low < high) {
            while(low < high && pivot <= array[high]) { high-- ; }
            swap(array, low, high) ;
            while(low < high && pivot >= array[low]) { low++ ; }
            swap(array, low, high) ;
        }

        return low ;
    }

快速排序(非递归版本)

    public static void quickSort(int[] array) {
        if(array==null || array.length==1) { return ; }

        //保存划分后所形成空间的左右端点
        Stack<Integer> stack = new Stack<Integer>() ;
        stack.push(0) ;
        stack.push(array.length - 1) ;
        int low, high ;
        while(! stack.isEmpty()) {
            high = stack.pop() ;
            low = stack.pop() ;

            if(low >= high) { continue ; }
            int i = partition(array, low, high) ;

            stack.push(low) ;   //保存左边的区间
            stack.push(i-1) ;

            stack.push(i+1) ;   //保存右边的区间
            stack.push(high) ;
        }
    }

    private static int partition(int[] array, int low, int high) {
        int pivot = array[low] ;

        while(low < high) {
            while(low < high && pivot <= array[high]) { high-- ; }
            swap(array, low, high) ;
            while(low < high && pivot >= array[low]) { low++ ; }
            swap(array, low, high) ;
        }

        return low ;
    }

堆排序

    public static void heapSort(int[] heap) {
        buildHeap(heap) ;   //构建堆

        for(int size=heap.length-1 ; size >= 1 ; ) {
            swap(heap, 0, size);    //交换首末元素
            adjustHeap(heap, --size, 0);  //对剩余元素进行调整
        }
    }

    public static void buildHeap(int[] heap) {
        int size = heap.length-1 ;
        //自底向上调整堆
        for(int begin = size/2 ; begin>=0 ; begin--){
            adjustHeap(heap, size, begin) ;
        }
    }

    public static void adjustHeap(int[] heap, int size, int start) {
        int big = start ;   //保存较大元素下标
        int left = 2*start + 1 ;    //左叶子节点
        int right = 2*start + 2 ;   //右叶子节点
        while(left<=size || right<=size) {
            if(left<=size && heap[left]>heap[big]) { big=left ; }
            if(right<=size && heap[right]>heap[big]) { big=right ; }

            if(start == big) {  break ; }   //调整完毕
            else {
                swap(heap, start, big) ;    //较大元素上浮
                start = big ;
                left = 2*start + 1 ;
                right = 2*start + 2 ;
            }
        }
    }
展开阅读全文
打赏
0
11 收藏
分享
加载中
更多评论
打赏
0 评论
11 收藏
0
分享
返回顶部
顶部