排序

排序的方法有很多种:下面实现冒泡法排序,选择法排序,插入法排序,归并排序,希尔排序,快速排序

package org.exam.order;
import org.junit.Test;
/**
 * Created by xin on 15.10.23.
 */
public class App {
    private int[] arr={31,23,34,78,26,29,25,41,39,27};
    public void display(){
        for (int i = 0; i <arr.length ; i++) {
            System.out.print(arr[i]+" ");
        }
        System.out.println();
    }
    private void swap(int one, int two) {
        int temp = arr[one];
        arr[one] = arr[two];
        arr[two] = temp;
    }
    //-----------bubbleSort start----------------------
    public void bubbleSort() {
        for (int out = arr.length - 1; out > 1; out--) {
            for (int in = 0; in < out; in++) {
                if (arr[in] > arr[in + 1]) {
                    swap(in, in + 1);
                }
            }
        }
    }
    //-----------bubbleSort end------------------------
    //-----------selectionSort start----------------------
    public void selectionSort() {
        int out, in, min;
        for (out = 0; out < arr.length - 1; out++) {
            min = out;
            for (in = out + 1; in < arr.length; in++) {
                if (arr[in] < arr[min]) {
                    min = in;
                }
            }
            swap(out, min);
        }
    }
    //-----------selectionSort end------------------------
    //-----------insertSort start----------------------
    public void insertSort(){
        for (int out = 1; out < arr.length; out++) {
            int tmp= arr[out];//要插入的项,从第二项开始插入
            int in=out-1;
            while (in>=0&& arr[in]>tmp){//项数比较大时,可考虑用二分法找到插入位置
                arr[in+1]= arr[in];
                in--;
            }
            arr[in+1]=tmp;
        }
    }
    //-----------insertSort end------------------------
    //-----------recMergeSort start----------------------
    private void recMergeSort(int[] workSpace, int lower, int upper) {
        if (lower==upper){
            return;
        }else{
            int mid=(lower+upper)/2;
            recMergeSort(workSpace,lower,mid);
            recMergeSort(workSpace,mid+1,upper);
            merge(workSpace,lower,upper);
        }
    }
    private void merge(int[] workSpace,int lower, int upper) {
        int mid=(lower+upper)/2,size = upper-lower+1;
        int cur = 0,curA = lower,curB= mid+1;
        while(curA <= mid && curB <= upper) {
            if (arr[curA] < arr[curB]) {
                workSpace[cur++] = arr[curA++];
            }else {
                workSpace[cur++] = arr[curB++];
            }
        }
        while(curA <= mid) {
            workSpace[cur++] = arr[curA++];
        }
        while(curB <= upper) {
            workSpace[cur++] = arr[curB++];
        }
        //已经在workSpace前面部分排好序,复制过来覆盖
        for(int i=0; i<size; i++) {
            arr[lower + i] = workSpace[i];
        }
    }
    //-----------recMergeSort end------------------------
    //-----------shellSort start----------------------
    public void shellSort() {
        int tmp;
        int h = 1;
        while (h <= arr.length / 3) {
            h = 3 * h + 1;
        }
        while (h > 0) {
            /**
             * 假设h=4,arr为14个数的数组(下标从0开始),此程序并不是按(arr[0],arr[4],arr[8],arr[12]),(arr[1],arr[5],arr[9],arr[13]),(arr[2],arr[6],arr[10]),(arr[3],arr[7],arr[11])进行的,
             * 当i=4时,可认为只有a[0]一个元素这一组的基础上插入a[4],同理当i=5时,可认为只有a[1]一个元素这一组的基础上插入a[5],同理当i=6时,可认为只有a[2]一个元素这一组的基础上插入a[6],同理当i=7时,可认为只有a[3]一个元素这一组的基础上插入a[7]
             * 直至当i=8时,可认为有(arr[0],arr[4])的基础上插入a[8],并且arr[0]与arr[4]是有序的.同理当i=9时,可认为有(arr[1],arr[5])的基础上插入a[9],并且arr[1]与arr[5]是有序的...
             * 直至i=12时,可认为有(arr[0],arr[4],a[8])的基础上插入a[12],并且arr[0],arr[4],a[8]是有序的...
             */
            for (int i = h; i < arr.length; i++) {//当h=1时,此层for为基本的插入法排序
                tmp = arr[i];
                int j = i;
                while (j > h - 1 && arr[j - h] > tmp) {
                    arr[j] = arr[j - h];
                    j -= h;
                }
                arr[j] = tmp;
            }
            h = (h - 1) / 3;
        }
    }
    //-----------shellSort end------------------------
    //-----------quickSort start----------------------
    public void quickSort(int left,int right){
        int size=right-left+1;
        if (size<10){//由于中值划分至少有4个项,所以当size>3时,不到走向这个else.当项数小于10时,采用插入法替代是更好的选择.
            insertSort(left, right);
        }else{
            int pivot=medianOf3(left,right);
            int position=partition(left,right,pivot);
            quickSort(left, position - 1);
            quickSort(position + 1, right);
        }
    }
    private int partition(int left,int right,int pivot){
        int leftPtr=left;//经过medianOf3排序,组最左项会不大于pivot,所以最初左指针应指向left
        int rightPtr=right-1;//经过medianOf3排序,组最右项会不小于pivot,再有right-1为pivot,所以最初右指针应指向right-1
        while (true){
            while (arr[++leftPtr]<pivot){
            }
            while (arr[--rightPtr]>pivot){
            }
            if (leftPtr>=rightPtr){
                break;
            }else{
                swap(leftPtr,rightPtr);
            }
        }
        swap(leftPtr,right-1);//将pivot移至leftPtr,并返回其位置
        return leftPtr;
    }
    private void insertSort(int left, int right) {
        for (int out = left + 1; out <= right; out++) {
            int temp = arr[out];
            int in = out;
            while (in > left && arr[in - 1] >= temp) {
                arr[in] = arr[in - 1];
                --in;
            }
            arr[in] = temp;
        }
    }
    private int medianOf3(int left, int right) {/** 经过medianOf3排序,组最左项肯定小于或等于pivot,并且返回右二项为pivot */
        int center=(left+right)/2;
        if (arr[left]>arr[center]){
            swap(left,center);
        }
        if (arr[left]>arr[right]){
            swap(left,right);
        }
        if (arr[center]>arr[right]){
            swap(center,right);
        }
        swap(center,right-1);
        return arr[right-1];
    }
    //-----------quickSort end------------------------
    @Test
    public void bubble(){
        System.out.print("冒泡法排序:");
        bubbleSort();
        display();
    }
    @Test
    public void selection(){
        System.out.print("选择法排序:");
        selectionSort();
        display();
    }
    @Test
    public void insert(){
        System.out.print("插入法排序:");
        insertSort();
        display();
    }
    @Test
    public void recMerge(){
        System.out.print("归并排序:");
        int[] workSpace=new int[arr.length];//新开辟一个一样大小的数组,实际上用到的空间可能都不到一半
        recMergeSort(workSpace,0,arr.length-1);
        display();
    }
    @Test
    public void shell(){
        System.out.print("希尔排序:");
        shellSort();
        display();
    }
    @Test
    public void quick(){
        System.out.print("快速排序:");
        quickSort(0, arr.length - 1);
        display();
    }
}


你可能感兴趣的:(排序,归并排序,冒泡法排序,选择法排序,插入法排序)