各种排序

快速排序:

     /* 快速排序 */
     //直接交换,better
    static int partition(Integer arr[],int low,int high){
        int temp,pivot = arr[high];
         while(low < high){        
             /* 查找顺序要和基准选取方向相反;
              pivot = arr[high] 则必须先从low开始;
               反之 pivot = arr[low], 则必须先从high开始查找 */
            while(arr[low] <= pivot && low < high)
                low++; 
            arr[high] = arr[low];//直接覆盖原先的元素
            while(arr[high] >= pivot && low < high)
                high--;  
            arr[low] = arr[high];
        }
        // 校准,将基准移至正确位置
        arr[low] = pivot;
        System.out.println("low="+low+";high="+high);
        return low;
    }

     static void  quickSort(Integer []arr,int low,int high){
         if(low < high){
          int pivotpos = partition(arr,low,high);
          quickSort(arr,low,pivotpos-1);
          quickSort(arr,pivotpos+1,high);
         }
    }

另一种:

    static int partition(Integer a[], int low, int high) {
        int i = low, j = high;
        int temp, pivot = a[i];
        while (i < j) {
            /*
             * 查找顺序要和基准选取相反; pivot = arr[high] 则必须先从low开始; 
             * 反之 pivot =arr[low],则必须先从high开始查找
             */
            /**
             * 注意:
             * 1,与pivot比较必须是>=,否则在a[j]或a[i]==pivot时,会造成死循环
             * 2,内层循环的i<j,保证i,j不会越过对方,因此跳出最外层循环时,i==j
             */
            while (a[j] >= pivot && i < j)
                j--;
            while (a[i] <= pivot && i < j)
                i++;
            // i,j位置元素,两边交换,此时无需判断i<=j,此条件在该循环中恒成立
            int t = a[i];
            a[i] = a[j];
            a[j] = t;
        }
        // 校准,将基准值移至正确位置,此时i==j
        a[low] = a[i];
        a[i] = pivot;
        System.out.println("i=" + i + ";j=" + j);// i j必相等
        return i;// 返回基准所在位置划分位置
    }

    static void quickSort(Integer[] a, int low, int high) {
        if (low < high) {
            int pivotpos = partition(a, low, high);
            quickSort(a, low, pivotpos - 1);
            quickSort(a, pivotpos + 1, high);
        }
    }

    public static void main(String[] args) {
         Integer a[] = { 8,1,4,9,0,3,5,2,7,6};
        quickSort(a, 0, a.length - 1);
        Arrays.toString(a);

    }

第二种
low处自始至终放的是pivot没动,最后需要把i,j指向位置的元素放到low处;
解释为什么满足放到low处:
内层两个while,先从high走,再走low;最后一次while时肯定是先不满足第一个while,第二个while又是i==j不满足;不满足第一个while但是又进得了外层的while,只能说明最后i(或j)指向的元素不满足>=pivot,即元素肯定小于pivot,所以必定满足放到low处。
这也就是为什么“查找顺序要和基准选取的方向相反

归并排序:

//将有二个有序数列a[first...mid]和a[mid...last]合并。  
void mergearray(int a[], int first, int mid, int last, int temp[])  
{  
    int i = first, j = mid + 1;  
    int m = mid,   n = last;  
    int k = 0;  

    while (i <= m && j <= n)  
    {  
        if (a[i] <= a[j])  
            temp[k++] = a[i++];  
        else  
            temp[k++] = a[j++];  
    }  

    while (i <= m)  
        temp[k++] = a[i++];  

    while (j <= n)  
        temp[k++] = a[j++];  

    for (i = 0; i < k; i++)  
        a[first + i] = temp[i];  
}  
void mergesort(int a[], int first, int last, int temp[])  
{  
    if (first < last)  
    {  
        int mid = (first + last) / 2;  
        mergesort(a, first, mid, temp);    //左边有序  
        mergesort(a, mid + 1, last, temp); //右边有序  
        mergearray(a, first, mid, last, temp); //再将二个有序数列合并  
    }  
}  

bool MergeSort(int a[], int n)  
{  
    int *p = new int[n];  
    if (p == NULL)  
        return false;  
    mergesort(a, 0, n - 1, p);  
    delete[] p;  
    return true;  
}  

归并排序的效率是比较高的,设数列长为N,将数列分开成小数列一共要logN步,每步都是一个合并有序数列的过程,时间复杂度可以记为O(N),故一共为O(N*logN)。因为归并排序每次都是在相邻的数据中进行操作,所以归并排序在O(N*logN)的几种排序方法(快速排序,归并排序,希尔排序,堆排序)也是效率比较高的。
https://visualgo.net/sorting 排序可视化

堆排序

计算堆化时间复杂度时,将父节点与子节点的比较简易化,看本质(其实就是从上到下的单支链表!因为选择堆化结点时,是先从n/2处向前遍历。从上到下比较时,调整的必是或左或右的一颗子树。其实无论是否下面的一堆化,向下调整时,每次选择必走的是单支的啊。。。),其实是该节点的深度(树高H-本层高度h)
http://blog.csdn.net/yuzhihui_no1/article/details/44258297
该博客代码,时间复杂度 均解释十分详细

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值