标签:
每次取剩下的一个元素插入到已经有序的序列中.
public static void InsertSort(int[] arr){
        if(arr == null || arr.length == 0){
            System.err.println("ERROR INPUT");
            return;
        }
        int n = arr.length;
        for(int i = 1; i < n; i++){
            int temp = arr[i];
            int j = i - 1;
            while(j >= 0 && temp < arr[j]){
                arr[j+1] = arr[j];
                j--;
            }
            arr[j+1] = temp;
        }
    }
*最好情况下:每次循环,内层都不需要比较,只有外层循环的常量级操作,时间复杂度为O(n)
*最坏情况下:内层循环每次都要比较i次,故总的执行次数是:1+2+3+…+n=n*(n-1)/2,故时间复杂度为O(n2 )
*最后平均时间复杂度为:O(n2 )
*空间复杂度:O(1)
基本思想与直接插入是一样的,区别在于寻找插入位置的方法不同,折半插入排序是采用折半查找来寻找插入位置的.
public static void halfInsertSort(int[] arr){
        if(arr == null || arr.length == 0){
            System.err.println("ERROR INPUT");
            return;
        }
        for(int i = 1; i < arr.length; i++){
            int temp = arr[i];
            int low = 0;
            int high = i - 1;
            int idx = -1;
            while(low <= high){
                int m = (low+high)/2;
                if(arr[m] < temp){
                    low = m+1;
                }else if(arr[m] > temp){
                    high = m-1;
                }else{
                    idx = m+1;
                    break;
                }
            }
            if(low > high){
                idx = high + 1;
            }
            for(int j = i-1; j >= idx; j--){
                arr[j+1] = arr[j];
            }
            arr[idx] = temp;
        }
    }
*外层循环为n-1次,内层循环是折半查找,
*最好情况是:复杂度为O(logn ).故总的时间复杂度为O(nlogn );最坏情况是O(n2 );平均情况为O(n2 ).
*空间复杂度为:O(1)
希尔排序,又称缩小增量排序,其本质还是插入排序,只不过将待排序的序列按某种规则分为几个子序列,分别对这几个子序列进行直接插入排序.这个规则就是增量
比如对序列:49, 38, 65, 97, 76, 13, 27, 49
先选择3为增量,则得到序列1:49, 97, 27;序列2:38,76, 49;序列3:65, 13
分别对这三个使用直接插入排序,序列1:27,49,97;序列2:38,49,76;序列3:13,65
将三个序列合并起来:27,38,13,49,49,65,97,76
这就是一趟希尔排序了.接下来,再也2(或1)为增量进行一趟希而排序
平均时间复杂度:
O(nlogn) 
空间复杂度:O(1) 
每次通过一系列的交换动作,将最大(或最小)的数字冒出来.终止条件是一趟排序过程中没有发生元素交换
public static void BubbleSort(int[] arr){
        if(arr == null || arr.length == 0){
            System.err.println("Error input");
            return;
        }
        for(int i = arr.length-1; i >= 1; i--){
            boolean flag = false;
            for(int j = 0; j < i; j++){
                if(arr[j] > arr[j+1]){
                    int temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                    flag = true;
                }
            }
            if(flag == false){
                return;
            }
        }
    }
时间复杂度:最好
O(n) 最坏O(n2) 平均O(n2) 
空间复杂度:O(1) 
>快速排序也是"交换"类的排序,它的基本思想是找出一个枢纽,使得在它左边的比它小,右边的比它大.
public static void QuickSort(int[] arr, int l, int r){
        if(arr == null || arr.length == 0 || l < 0 || r >= arr.length){
            System.err.println("ERROR INPUT");
            return;
        }
        int i = l;
        int j = r;
        if(l < r){
            int temp = arr[l];
            while(i != j){
                while(j > i && arr[j] > arr[i]){
                    j--;
                }
                if(i < j){
                    arr[i] = arr[j];
                    i++;
                }
                while(j > i && arr[i] < arr[j]){
                    i++;
                }
                if(i < j){
                    arr[j] = arr[i];
                    j--;
                }
            }
            arr[i] = temp;
            QuickSort(arr, l, i-1);
            QuickSort(arr, i+1, r);
        }
    }
另外一个写法:
    public int Partition(char[] arr, int start, int end){
        if(arr == null || arr.length == 0 || start < 0 || end < 0){
            return -1;
        }
        int index = start + (int)(Math.random() * ((end - start) + 1));//随机选择一个作为标杆的数字
        //将标杆放在数组最后一位
//        System.out.println(arr.toString());
//        System.out.println(arr[index]);
//        System.out.println(arr[end]);
        char tmp = arr[index]; arr[index] = arr[end]; arr[end] = tmp;
        int small = start - 1;//small用来存储从右到左第一个小于标杆的数字的下标
        for(index = start; index < end; index++){
            if(arr[index] < arr[end]){//如果小于标杆
                small++;//更新第一个小的
                if(small != index){//如果当前遍历的不是第一个小的
                    tmp = arr[index];arr[index] = arr[small];arr[small] = tmp;//将当前遍历的数字放在第一个小的位置上
                }
            }
        }
        //由于small指示的是从右到左第一个小于标杆的,而此时标杆还放在数组最后,因此,应该将标杆放在small后面一位。
        small++;
        tmp = arr[small];arr[small] = arr[end]; arr[end] = tmp;
        return small;//返回位置为所选择的标杆最后的位置
    }
    public void QuickSort(char[] arr, int start, int end){
        if(start == end){
            return;
        }
        int index = Partition(arr, start, end);
        if(index > start){
            QuickSort(arr, start, index - 1);
        }
        if(index < end){
            QuickSort(arr, index + 1, end);
        }
    }
时间复杂度:最好
O(nlog2n) ,平均O(nlog2n) ,最坏:O(n2) 
空间复杂度O(log2n) 
快速排序是所有排序算法中最好的.
简单选择排序采用最简单的选择方式,从头至尾顺序扫描序列,找出最小的一个记录,和第一个记录交换,接着从剩下的记录中继续这种选择和交换,最终使序列有序.
    public static void SimpleSelectSort(int[] arr){
        if(arr == null || arr.length == 0){
            System.err.println("ERROR INPUT");
            return;
        }
        for(int i = 0; i < arr.length; i++){
            int temp = arr[i];
            int min = arr[i];
            int idx = i;
            for(int j = i; j < arr.length; j++){
                if(arr[j] < min){
                    min = arr[j];
                    idx = j;
                }
            }
            arr[idx] = temp;
            arr[i] = min;
        }
    }
时间复杂度:
O(n2) 
空间复杂度:O(1) 
将序列调整成一个堆.
/**
     * 本函数完成对在数组R[low]到R[high]范围内对在位置low上的结点进行调整
     * @param arr
     * @param low
     * @param high
     */
    public static void shift(int[] arr, int low, int high){
        if(arr == null || arr.length == 0){
            return;
        }
        int i = low;
        int j = 2 * i;//arr[j]是arr[i]的左孩子结点
        int temp = arr[i];
        while(j <= high){
            if(j < high && arr[j] < arr[j+1]){//若右孩子较大,则把j指向右孩子
                j++;                        //j变为2*i+1
            }
            if(temp < arr[j]){//将R[j]调整到双亲位置上
                arr[i] = arr[j];
                i = j;
                j = 2 * i;
            }else{
                break;//调整结束
            }
        }
        arr[i] = temp;//被调整结点的值放入最终位置
    }
    /**
     * 堆排序函数
     * @param arr
     */
    public static void heapSort(int[] arr){
        if(arr == null || arr.length == 0){//输入参数的非法性检查
            System.err.println("ERROR INPUT");
            return;
        }
        int i;
        int temp;
        int n = arr.length;
        for(i = n / 2; i >= 0; i--){//建立初始堆
            shift(arr, i, n-1);
        }
        for(i = n-1; i >= 1; i--){//进行n-1次循环完成堆排序
            temp = arr[0];
            arr[0] = arr[i];
            arr[i] = temp;
            shift(arr, 0, i-1);//在减少了1个元素的无序序列中进行调整
        }
    }
时间复杂度:
O(nlog2n) 
空间复杂度:O(1) 
初始状态是每个元素是一个子序列,然后两两合并,形成了几个两个元素的子序列,....,依次合并下去,直到合并为一个有序序列.
时间复杂度:
O(nlog2n) 
空间复杂度:O(n) 
时间复杂度:
O(d(n+rd)) 
空间复杂度:O(rd) 
"快些以
O(nlog2n) 的速度归队"
即快,希,归,堆都是O(nlog2n) ,其他都是O(n2) ,基数排序例外,是O(d(n+rd)) 
快排
O(log2n) 
归并O(n) 
基数O(rd) 
其他O(1) 
"心情不稳定,快些找一堆朋友聊天吧"
即不稳定的有:快,希,堆
标签:
原文地址:http://blog.csdn.net/lilianforever/article/details/51906771