sort

 排序有内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存。

 以下是本人写的排序法

public class Shit {

    private static int ARRAY[] = new int[] { 17, 12, 7, 75, 11, 22, 3, 45, 1,
            89, 56, 14, 10 };

    public static void main(String t[]) {
        print(ARRAY);
        // bubbleSort(ARRAY);
        quickSort(ARRAY, 0, ARRAY.length - 1);
        // mergeSort(ARRAY, 0, ARRAY.length - 1);
        // insertSort(ARRAY);
        // selectSort(ARRAY);
        // shellSort(ARRAY);
        // shellPrioritySort(ARRAY);
        // shellMostSort(ARRAY);
        // heapSort(ARRAY);
        print(ARRAY);

    }

    public static void print(int array[]) {
        for (int i : array) {
            System.out.print(i + " ");
        }

        System.out.println();
    }

    // 冒泡排序法算法复杂度O(n^2), 属于稳定的排序法
    public static void bubbleSort(int array[]) {
        int temp;
        int size = array.length;

        for (int i = 0; i < size - 1; i++) {
            for (int j = 0; j < size - i - 1; j++) {
                if (array[j] > array[j + 1]) {
                    temp = array[j];
                    array[j] = array[j + 1];
                    array[j + 1] = temp;
                }
            }
        }
    }

    // 选择排序法算法复杂度O(n^2), 属于稳定的排序法
    public static void selectSort(int array[]) {
        int i, j, k, temp;
        int size = array.length;

        for (i = 0; i < size - 1; i++) {
            k = 0;

            for (j = 1; j < size - i; j++) {
                if (array[j] >= array[k]) {
                    k = j;
                }
            }

            temp = array[size - i - 1];
            array[size - i - 1] = array[k];
            array[k] = temp;
        }
    }

    // 插入排序法算法稳定, 复杂度最低n,最高O(n^2), 平均复杂度:O(n^2), 适合序列已经大致排序的情况
    public static void insertSort(int array[]) {
        int size = array.length;
        int i, j, temp;

        for (i = 1; i < size; i++) {
            if (array[i] < array[i - 1]) {
                temp = array[i];
                j = i - 1;
                while (j >= 0 && array[j] > temp) {
                    array[j + 1] = array[j];
                    j--;
                }

                array[j + 1] = temp;
            }
        }
    }

    // 快速排序法算法复杂度O(nlogn),属于不稳定的排序法,可节省空间
    public static void quickSort(int array[], int left, int right) {
        if (left >= right) {
            return;
        }

        int i = left;
        int j = right;
        int key = array[left];

        while (i < j) {
            while (i < j && array[j] > key) {
                j--;
            }

            if (i < j) {
                array[i++] = array[j];
            }

            while (i < j && array[i] < key) {
                i++;
            }

            if (i < j) {
                array[j] = array[i];
            }
        }

        array[i] = key;

        quickSort(array, left, i - 1);
        quickSort(array, i + 1, right);
    }

    // 归并排序算法稳定,数组需要O(n)的额外空间,链表需要O(log(n))的额外空间,时间复杂度为O(nlog(n))
    public static void mergeSort(int array[], int left, int right) {
        if (left >= right) {
            return;
        }

        int center = (left + right) >> 1;
        mergeSort(array, left, center);
        mergeSort(array, center + 1, right);

        int i = left;
        int j = center + 1;
        int k = 0;

        int copyArray[] = new int[right - left + 1];

        while (i <= center && j <= right) {
            if (array[i] <= array[j]) {
                copyArray[k++] = array[i++];
            } else {
                copyArray[k++] = array[j++];
            }
        }

        while (i <= center) {
            copyArray[k++] = array[i++];
        }

        while (j <= right) {
            copyArray[k++] = array[j++];
        }

        System.arraycopy(copyArray, 0, array, left, right - left + 1);
    }

    // shell排序原生算法
    public static void shellSort(int array[]) {
        int gap, i, j, k, temp;
        int size = array.length;

        for (gap = size >> 1; gap > 0; gap >>= 1) {
            for (i = 0; i < gap; i++) {
                for (j = i + gap; j < size; j += gap) {
                    if (array[j] < array[j - gap]) {
                        temp = array[j];
                        k = j - gap;
                        while (k >= 0 && array[k] > temp) {
                            array[k + gap] = array[k];
                            k = k - gap;
                        }

                        array[k + gap] = temp;
                    }
                }
            }
        }
    }

    // 改进的shell排序算法,算法变简单了,原理几乎没变,复杂度也完全没变,这个是比较推荐的算法
    public static void shellPrioritySort(int array[]) {
        int gap, i, j, temp;
        int size = array.length;

        for (gap = size >> 1; gap > 0; gap >>= 1) {
            for (i = gap; i < size; i++) {
                // 使用while循环,不要使用for循环,这样更效率
                if (array[i] < array[i - gap]) {
                    temp = array[i];
                    j = i - gap;
                    while (j >= 0 && array[j] > temp) {
                        array[j + gap] = array[j];
                        j = j - gap;
                    }

                    array[j + gap] = temp;
                }
            }
        }
    }

    // shell算法的简化版,代码变得更简单,但是由于频繁的swap操作,显然没有前面两个shell算法快,
    public static void shellMostSort(int array[]) {
        int gap, i, j, temp;
        int size = array.length;

        for (gap = size >> 1; gap > 0; gap >>= 1) {
            for (i = gap; i < size; i++) {
                for (j = i - gap; j >= 0 && array[j] > array[j + gap]; j -= gap) {
                    temp = array[j];
                    array[j] = array[j + gap];
                    array[j + gap] = temp;
                }
            }
        }
    }

    public static void heapSort(int array[]) {
        int size = array.length;
        int i, temp;

        // build heap
        int middle = size >> 1;
        for (i = middle; i >= 0; i--) {
            adjustHeap(array, size, i);
        }

        // heap sort
        int index = size - 1;
        while (index > 0) {
            temp = array[index];
            array[index] = array[0];
            array[0] = temp;
            adjustHeap(array, index, 0);
            index--;
        }
    }

    // 堆化以root为节点的子树
    public static void adjustHeap(int array[], int restSize, int root) {
        int left, right, largeIndex, temp;

        left = (root << 1) + 1;
        right = left + 1;
        largeIndex = root;

        while (left < restSize || right < restSize) {
            if (left < restSize && array[left] >= array[largeIndex]) {
                largeIndex = left;
            }

            if (right < restSize && array[right] >= array[largeIndex]) {
                largeIndex = right;
            }

            if (largeIndex != root) {
                temp = array[largeIndex];
                array[largeIndex] = array[root];
                array[root] = temp;

                root = largeIndex;
                left = (root << 1) + 1;
                right = left + 1;
                continue;
            }

            break;
        }

        // //这里用递归实现,不推荐递归的方法
        // if (root > (restSize >> 1)) {
        // return;
        // }
        //
        // int left, right, largeIndex, temp;
        // left = (root << 1) + 1;
        // right = left + 1;
        // largeIndex = root;

        // if (left < size && array[left] >= array[largeIndex]) {
        // largeIndex = left;
        // }
        //
        // if (right < size && array[right] >= array[largeIndex]) {
        // largeIndex = right;
        // }
        //
        // if (largeIndex != root) {
        // temp = array[largeIndex];
        // array[largeIndex] = array[root];
        // array[root] = temp;
        // adjustHeap(array, size, largeIndex);// 这里用递归实现
        // }
    }
}

 

 

package sortdemo;

import java.util.Arrays;

public class HeapSort {
    public static void main(String []args){
        int []arr = {9,8,7,6,5,4,3,2,1};
        sort(arr);
        System.out.println(Arrays.toString(arr));
    }
    public static void sort(int []arr){
        //1.构建大顶堆
        for(int i=arr.length/2-1;i>=0;i--){
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(arr,i,arr.length);
        }
        //2.调整堆结构+交换堆顶元素与末尾元素
        for(int j=arr.length-1;j>0;j--){
            swap(arr,0,j);//将堆顶元素与末尾元素进行交换
            adjustHeap(arr,0,j);//重新对堆进行调整
        }

    }

    /**
     * 调整大顶堆(仅是调整过程,建立在大顶堆已构建的基础上)
     * @param arr
     * @param i
     * @param length
     */
    public static void adjustHeap(int []arr,int i,int length){
        int temp = arr[i];//先取出当前元素i
        for(int k=i*2+1;k<length;k=k*2+1){//从i结点的左子结点开始,也就是2i+1处开始
            if(k+1<length && arr[k]<arr[k+1]){//如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if(arr[k] >temp){//如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];
                i = k;
            }else{
                break;
            }
        }
        arr[i] = temp;//将temp值放到最终的位置
    }

    public static void swap(int []arr,int a ,int b){
        int temp=arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

 

posted @ 2015-03-03 15:34  牧 天  阅读(175)  评论(0)    收藏  举报