java高级排序

Java排序算法精讲
本文深入探讨了四种高级排序算法:快速排序、归并排序、桶排序和堆排序的实现原理及Java代码实现。详细介绍了每种算法的时间复杂度、算法流程及策略,并提供了具体的Java代码实现。

本文主要通过java代码实现java中相关高级的排序算法

1 快速排序

package com.sort.advance;

/**
 * Created by jack on 2018/3/25.
 * 快速排序
 * 算法时间复杂度
 *  最好:T(n)= O(nlogn)
 *  最坏:T(n)= O(n*n)n次比较和n次移动
 *
 * 算法流程:
 *  在数组中选择一个称为主元(pivot)的元素,将数组分为两部分,使得 第一部分中的所有元素都小于或等于主元,而第二部分的所有元素都大于主元
 *  对第一部分递归地应用快速排序算法,然后对第二部分递归地应用快速排序算法
 *
 *  算法策略:
 *      二分法+递归
 */
public class QuickSort {
    /**
     *
     * @param arr 原始数组
     * @param left 从第一个元素开始
     * @param right 从最后一个元素开始
     * @param point 数组中第一个元素的值
     * @return
     */
    public static int partition(long arr[],int left, int right,long point) {
        int leftPtr = left - 1;
        int rightPtr = right;
        while(true) {
            //循环,将比关键字小的留在左端
            while(leftPtr < rightPtr && arr[++leftPtr] < point);
            //循环,将比关键字大的留在右端
            while(rightPtr > leftPtr && arr[--rightPtr] > point);
            if(leftPtr >= rightPtr) {
                break;
            } else {
                long tmp = arr[leftPtr];
                arr[leftPtr] =  arr[rightPtr];
                arr[rightPtr] = tmp;
            }
        }
        //将关键字和当前leftPtr所指的这一个进行交换
        long tmp = arr[leftPtr];
        arr[leftPtr] =  arr[right];
        arr[right] = tmp;
        return leftPtr;
    }

    public static void displayArr(long[] arr) {
        System.out.print("[");
        for(long num : arr) {
            System.out.print(num + " ");
        }
        System.out.print("]");
        System.out.println();
    }

    /**
     *
     * @param arr 原始数组
     * @param left 从第一个元素开始
     * @param right 从最后一个元素开始
     */
    public static void sort(long[] arr, int left, int right) {
        if(right - left <= 0) {
            return;
        } else {
            //设置关键字 默认是数组最后一个元素
            long point = arr[right];
            //获得切入点,同时对数组进行划分
            int partition = partition(arr, left, right, point);
            //System.out.println("partition:"+partition);
            //对左边的子数组进行快速排序
            sort(arr,left,partition - 1);
            //对右边的子数组进行快速排序
            sort(arr,partition + 1, right);
        }
    }

    public static void main(String[] args) {
        long[] arr  ={1,3,2,4,5,7,6,10,9};
        QuickSort.displayArr(arr);
        QuickSort.sort(arr, 0, arr.length - 1);
        QuickSort.displayArr(arr);
    }
}

2 归并排序

package com.sort.advance;

import java.util.Arrays;

/**
 * Created by jack on 2018/3/24.
 * 归并排序:都有有序的序列列表合并成一个新的
 *
 * 算法本质:递归排序+合拼
 *
 * 算法流程
 *  把待排序序列分为若干个子序列,每个子序列是有序的
 *  然后再把有序子序列合并为整体有序序列
 *
 * 算法复杂度:O(nlogn)
 */
public class MergeSort {

    /**
     * 多个有序列表归并一个整的有序列表
     * @param nums
     * @param low
     * @param mid
     * @param high
     */
    public static void merge(int[] nums, int low, int mid, int high) {
        int[] temp = new int[high - low + 1];
        int i = low;// 左指针
        int j = mid + 1;// 右指针
        int k = 0;

        // 把较小的数先移到新数组中
        while (i <= mid && j <= high) {
            if (nums[i] < nums[j]) {
                temp[k++] = nums[i++];
            } else {
                temp[k++] = nums[j++];
            }
        }

        // 把左边剩余的数移入数组
        while (i <= mid) {
            temp[k++] = nums[i++];
        }

        // 把右边边剩余的数移入数组
        while (j <= high) {
            temp[k++] = nums[j++];
        }

        // 把新数组中的数覆盖nums数组
        for (int k2 = 0; k2 < temp.length; k2++) {
            nums[k2 + low] = temp[k2];
        }
    }

    /**
     * 排序
     * @param nums
     * @param low
     * @param high
     * @return
     */
    public static int[] sort(int[] nums, int low, int high) {
        int mid = (low + high) / 2;
        if (low < high) {
            // 左边
            sort(nums, low, mid);
            // 右边
            sort(nums, mid + 1, high);
            // 左右归并
            merge(nums, low, mid, high);
        }
        return nums;
    }

    public static void main(String[] args) {
        int[] nums = { 2, 7, 8, 3, 1, 6, 9, 0, 5, 4 };
        MergeSort.sort(nums, 0, nums.length-1);
        System.out.println(Arrays.toString(nums));
    }

}

3 桶排序

package com.sort.advance;

/**
 * Created by jack on 2018/3/24.
 * 桶排序
 * 算法流程:桶的最大数量是大于数组中最大的元素的值+1
 *
 * 算法本质:空间换时间
 * 算法复杂度:
 *  线性的O(N+C),其中C=N*(logN-logM)。如果相对于同样的N,桶数量M越大,其效率越高,最好的时间复杂度达到O(N)
 */
@SuppressWarnings("all")
public class BucketSort {

    /**
     * 桶排序
     *
     * 参数说明:
     *     a -- 待排序数组
     *     max -- 数组a中最大值的范围
     */
    public static void bucketSort(int[] a, int max) {

        int[] buckets;

        if (a==null || max<1)
            return ;

        // 创建一个容量为max的数组buckets,并且将buckets中的所有数据都初始化为0        buckets = new int[max];

        // 1. 计数
        for(int i = 0; i < a.length; i++)
            buckets[a[i]]++;

        // 2. 排序
        for (int i = 0, j = 0; i < max; i++) {
            while( (buckets[i]--) >0 ) {
                a[j++] = i;
            }
        }

        buckets = null;
    }

    public static void main(String[] args) {
        int i;
        int a[] = {8, 2, 31, 4, 32, 6, 63, 34, 9};

        System.out.printf("before sort:");
        for (i = 0; i < a.length; i++)
            System.out.printf("%d ", a[i]);
        System.out.printf("\n");

        bucketSort(a, 64); // 桶排序

        System.out.printf("after  sort:");
        for (i = 0; i < a.length; i++)
            System.out.printf("%d ", a[i]);
        System.out.printf("\n");
    }
}

4 堆排序

4.1 构建堆信息

package com.sort.advance.heap;

/**
 * Created by jack on 2018/3/25.
 * 节点信息
 */
public class HeapNode {

    private int idata;

    public HeapNode(int key){
        idata = key;
    }

    public int getKey(){
        return idata;
    }

    public void setKey(int id){
        idata=id;
    }
}

4.2 堆基本操作

package com.sort.advance.heap;

/**
 * Created by jack on 2018/3/25.
 * 堆信息
 */
@SuppressWarnings("all")
public class Heap {

    private HeapNode[]heapArray;//存储堆的数组
    private int maxSize;//数组最大长度
    private int currentSize;//当前堆的大小

    public Heap(int max){
        maxSize = max;
        currentSize = 0;
        heapArray = new HeapNode[maxSize];
    }

    /**
     * 堆是否为空
     */

    public boolean isEmpty(){
        return currentSize==0;
    }

    /**
     * 新增元素
     */

    public boolean insert(int key){
        if (currentSize==maxSize)return false;//堆已经满了
        HeapNode newHeapNode = new HeapNode(key);
        heapArray[currentSize] = newHeapNode;//新节点放到数据最后位置
        trickleUP(currentSize);//向上调整
        currentSize++;
        return true;
    }


    /**
     * 新增元素-堆排序的
     */
    public void insertAt(int index,HeapNode heapNode){
        heapArray[index]= heapNode;
    }

    public void incrementSize(){
        currentSize++;
    }

    /**
     * 向上调整 从0开始
     */
    public void trickleUP(int index){
        int parent=(index-1)/2;
        HeapNode bottom = heapArray[index];
        // parent=0 代表已经是跟节点 不需要调整
        //如果当前要移动的节点的值比父节点的大 那么就进行交换
        while(index>0 && heapArray[parent].getKey()<bottom.getKey()){
            heapArray[index]=heapArray[parent];
            index = parent;
            parent = (parent-1)/2;
        }
        heapArray[index]=bottom;

    }

    /**
     * 向下调整
     */

    public void trickleDown(int index){
        int largetChild;
        HeapNode top =heapArray[index];
        while (index<currentSize/2){
            int leftChild = 2*index+1;
            int rightChild = leftChild +1;
            if(rightChild<currentSize && heapArray[leftChild].getKey()<heapArray[rightChild].getKey())
                largetChild = rightChild;
            else
                largetChild = leftChild;
            if (top.getKey()>=heapArray[largetChild].getKey())break;
            heapArray[index] = heapArray[largetChild];
            index = largetChild;
        }
        heapArray[index]=top;

    }

    /**
     * 删除堆中元素-根元素
     */

    public HeapNode remove(){
        HeapNode root = heapArray[0];
        heapArray[0]=heapArray[--currentSize];//把最后一个数据项先移动到根节点
        trickleDown(0);//把新的根位置的数据项进行比较向下调整
        return root;
    }


    /**
     * 改变堆中的值
     */
    public boolean change(int index,int newvalue){
        //无效位置
        if (index<0 || index>=currentSize)return false;
        //获取老的值
        int oldvalue = heapArray[index].getKey();
        //设置新的值
        heapArray[index].setKey(newvalue);
        //老的值比新的值小 向上调整
        if(oldvalue<newvalue)trickleUP(index);
        else
            trickleDown(index);//向下调整
        return true;
    }

    /**
     * 显示堆信息
     */
    public void displayHeap(){
        System.out.print("heaparray:");

        for (int m=0;m<currentSize;m++)
            if (heapArray[m]!= null) System.out.print(heapArray[m].getKey()+" ");
            else System.out.println("--");
        System.out.println();


        //以树状形式显示
        int nBlanks=32;
        int itemsPerRow=1;
        int column=0;
        int j=0;
        String dots ="...................................";
        System.out.println(dots+dots);
        while (currentSize>0){
            if (column==0){
                for (int k = 0; k <nBlanks ; k++) {
                    System.out.print(' ');
                }
            }
            System.out.print(heapArray[j].getKey());
            if (++j==currentSize)break;
            if (++column==itemsPerRow){
                nBlanks/=2;
                itemsPerRow*=2;
                column=0;
                System.out.println();
            }
            else{
                for (int k = 0; k <nBlanks*2-2 ; k++) System.out.print(' ');
            }
        }
        System.out.println("\n"+dots+dots);
    }



    public void displayArray(){
        for (int i=0;i<maxSize;i++){
            System.out.print(heapArray[i].getKey()+" ");
        }
        System.out.println();
    }

}

4.3 堆测试

package com.sort.advance.heap;
import java.io.*;

/**
 * Created by jack on 2018/3/25.
 * 堆测试
 */
public class HeapApp {

    public static String getString()throws IOException{
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        return br.readLine();
    }

    public static char getChar()throws IOException{
        return getString().charAt(0);
    }

    public static int getInt()throws IOException{
        return Integer.parseInt(getString());
    }

    public static void main(String[] args)throws IOException {
        int value,value2;
        Heap heap = new Heap(31);
        boolean success;
        heap.insert(70);
        heap.insert(40);
        heap.insert(50);
        heap.insert(20);
        heap.insert(60);
        heap.insert(100);
        heap.insert(80);
        heap.insert(30);
        heap.insert(10);
        heap.insert(90);



        while (true){
            System.out.print("enter first letter of show,insert,remove,change:");
            int choice =getChar();
            switch (choice){
                case 's':
                    heap.displayHeap();
                    break;
                case 'i':
                    System.out.print("enter value to insert");
                    value=getInt();
                    success=heap.insert(value);
                    if (!success){
                        System.out.println("can not insert heap full");
                        break;
                    }
                case 'r':
                    if (!heap.isEmpty())heap.remove();
                    else System.out.println("heap is empty can not remove");
                    break;
                case 'c':
                    System.out.print("enter current index of item:");
                    value=getInt();
                    System.out.print("enter new key:");
                    value2=getInt();
                    success=heap.change(value,value2);
                    if (!success) System.out.println("invalid index");
                    break;
                default:
                    System.out.println("invalid entry\n");
            }
        }

    }
}

4.4 堆排序

package com.sort.advance.heap;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * Created by jack on 2018/3/25.
 * 堆排序
 */
public class HeapAppSort {

    private static String getString()throws IOException {
        InputStreamReader isr = new InputStreamReader(System.in);
        BufferedReader br = new BufferedReader(isr);
        return br.readLine();
    }



    private static int getInt()throws IOException{
        return Integer.parseInt(getString());
    }

    public static void main(String[] args)throws IOException {
        int size,j;
        System.out.print("enter number of items:");
        size=getInt();
        Heap heap = new Heap(size);
        for (j=0;j<size;j++){
            int random = (int) (Math.random()*100);
            HeapNode newnode = new HeapNode(random);
            heap.insertAt(j,newnode);
            heap.incrementSize();
        }
        System.out.print("随机添加元素到堆中:");
        heap.displayArray();

        for (j = size/2-1; j>=0; j--) {
            heap.trickleDown(j);
        }
        System.out.print("初始化一个最大堆:");
        heap.displayArray();

        for (j=size-1;j>=0;j--){
            HeapNode heapNode = heap.remove();
            heap.insertAt(j, heapNode);
        }
        System.out.print("对生成后的最大堆进行排序:");
        heap.displayArray();

    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值