常见排序算法汇总(中)

 

上篇文章讲到了:冒泡排序、插入排序、选择排序,这篇文章我们讲归并排序和快速排序。

常见排序算法汇总(上)

 

归并排序

归并排序主要把数组从中间分成两部分,然后对前后两部分进行排序下,再将排好序的两部分合并在一起,这样整个数组就有序了。

图片

图片

 代码实现:


public static void mergeSort(int[] arr) {
    sort(arr, 0, arr.length - 1);
}

public static void sort(int[] arr, int L, int R) {
    if(L == R) {
        return;
    }
    int mid = L + ((R - L) >> 1);
    sort(arr, L, mid);
    sort(arr, mid + 1, R);
    merge(arr, L, mid, R);
}

public static void merge(int[] arr, int L, int mid, int R) {
    int[] temp = new int[R - L + 1];
    int i = 0;
    int left = L;
    int right = mid + 1;
    // 比较左右两部分的元素,哪个小,把那个元素填入temp中
    while(left <= mid && right <= R) {
        temp[i++] = arr[left] < arr[right] ? arr[left++] : arr[right++];
    }
    // 上面的循环退出后,把剩余的元素依次填入到temp中
    // 以下两个while只有一个会执行
    while(left <= mid) {
        temp[i++] = arr[left++];
    }
    while(right <= R) {
        temp[i++] = arr[right++];
    }
    // 把最终的排序的结果复制给原数组
    for(i = 0; i < temp.length; i++) {
        arr[L + i] = temp[i];
    }
}

总结:归并排序是一种稳定的排序方法。和选择排序一样,归并排序的性能不受输入数据的影响,但表现比选择排序好的多,因为始终都是O(nlogn)的时间复杂度。代价是需要额外的内存空间。

 

快速排序

 如果要排序数组中下标从p到r之间的一组数据,我们选择p到r之间的任意一个数据作为pivot(分区点)。

遍历p到r之间的数据,将小于pivot的放到左边,将大于pivot的放到右边,将pivot放到中间。经过这一步骤之后,数组p到r之间的数据就被分成了三个部分,前面p到q-1之间都是小于pivot的,中间是pivot,后面的q+1到r之间是大于pivot的。

图片

可以用递归排序下标从p到q-1之间的数据和下标从q+1到r之间的数据,直到区间缩小为1,就说明所有的数据都有序了。

图片

代码实现:

public void quickSort(int[] arr, int left,int right){
    if (left >= right){
        return;
    }
    int key = arr[left];
    int i = left;
    int j = right;
    while (i < j){
        //j向左移,直到遇到比key小的值
        while (arr[j] >= key && i < j){
            j--;
        }
        //i向右移,直到遇到比key大的值
        while (arr[i] <= key && i < j){
            i++;
        }

        //i和j指定的元素交换
        if (i < j){
            int temp = arr[i];
            arr[i] = arr[j];
            arr[j] = temp;
        }
    }
    arr[left] = arr[i];
    arr[i] = key;
    quickSort(arr,left,i - 1);
    quickSort(arr,i + 1,right);
}

总结:快排是一种原地、不稳定的排序算法,在大部分情况下的时间复杂度都可以做到O(nlogn),只有在极端情况下,才会退化到O(n2),即分区点pivot选在了最边缘。

归并排序和快速排序的区别

图片

归并排序的处理过程是由下到上的,先处理子问题,然后再合并。而快排正好相反,它的处理过程是由上到下的,先分区,然后再处理子问题。归并排序虽然是稳定的、时间复杂度为O(nlogn)的排序算法,但是它是非原地排序算法。

图片

喜欢本文的话,可以关注一下公众号,每天定时更新一篇学习日记,让我们一起成长!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值