[算法] 简述快排和归并算法

排序算法

搜索是计算机中非常重要的步骤,但是从无序数据中寻找特定数字难度较大。有序数据可以提升算法效率,例如二分查找是基于有序数组搜索的

那么,有哪些常见的排序算法呢?

常见排序算法

接下来,我们介绍两种重要的分治(Divide and Conquer )排序算法

快速排序

分治算法将大问题转换为小问题,逐个解决小问题的过程中大问题迎刃而解

基本概念

选取一个目标元素pivot,然后将目标元素放到数组中正确的位置。然后根据排好序的元素,将数组切分为两个子数组,递归实现此过程。

过程

  1. 选择基准数pivot,这里选择排序序列最后一个元素
    图二

  2. 设定lohi指针,lo指针向右搜寻,如果寻找到第一个pivot大的元素停止移动;hi指针向左搜寻,如果寻找到第一个pivot小的元素停止移动,然后交换这两个元素
    图三

    --------->图四

  3. 重复2过程(已经交换的元素颜色突出表示)
    图五

  4. 此时lo >= hi条件满足,跳出循环,交换loR索引上的值
    图六

  5. 递归实现1~4过程
    图七

Java实现

private void quickSort(int[] arr, int lo, int hi) {  
    if (lo >= hi) return;  
    int key = partition(arr, lo, hi);  
    quickSort(arr, lo, key - 1);  
    quickSort(arr, key + 1, hi);  
}  
  
private int partition(int [] arr, int lo, int hi) {  
    int pivot = arr[hi];  
    int i = lo;  
    int j = hi - 1;  
    for (; ; ) {  
        while (i < hi && arr[i] < pivot) {  
            i++;  
        }    
        while (j > lo && arr[j] >= pivot) {  
            j--;  
        }       
        if (i >= j) break;  
        swap(arr, i, j);  
    }    
    swap(arr, i, hi);  
    return i;  
}  
  
private void swap(int [] arr, int i, int j) {  
    int temp = arr[i];  
    arr[i] = arr[j];  
    arr[j] = temp;  
}

归并排序

基本概念

归并排序同样基于分治算法,在归并算法中,我们将一个数组递归切分成不可再分的小数组,然后将每一对数组进行排序合并,最终得到排序后的数组。

过程

  • 切分
    以数组[9, -3, 5, 2, 6, 8, -6, 1, 3]为例
    图八

  • 合并
    例如已经经过排序合并的序列 [-3, 5, 9][2, 6]

    • i指针在原数组上滑动
    • left变量初始被赋值为左边界right变量初始被赋值为mid+1,左右指针在辅助数组上滑动
    • leftright进行比较,小的那一个赋值给arr[i],然后移动指针,若一方到达边界,则将另外一方赋值给arr[i]
      图九

    -------------->图十

Java实现

public void sort(int[] arr) {  
    int[] helper = new int[arr.length];  
    mergeSort(arr, helper, 0, arr.length - 1);  
}  
  
private void mergeSort(int[] arr, int[] helper, int lo, int hi){  
    if (hi - lo < 1) return;  
    int mid = lo + (hi - lo) / 2;  
    mergeSort(arr, helper, lo, mid);  
    mergeSort(arr, helper, mid + 1, hi);  
    merge(arr, helper, lo, mid, hi);  
}  
  
private void merge(int[] arr, int[] helper, int lo, int mid, int hi) {  
    if (hi + 1 - lo >= 0) 
	    System.arraycopy(arr, lo, helper, lo, hi + 1 - lo);
	      
    int left = lo, right = mid + 1;  
    for (int i = lo; i <= hi; i++) {  
        if (left > mid) {  
            arr[i] = helper[right++];  
        } else if (right > hi) {  
            arr[i] = helper[left++];  
        } else if (helper[right] < helper[left]) {  
            arr[i] = helper[right++];  
        } else {  
            arr[i] = helper[left++];  
        }    
    }
}

总结

  • 分治:将大问题切分为小问题
  • 快速排序:先排序、后切分
  • 归并排序:先切分、后排序

Leetcode参考题目

Sort an Array (912)
Sort Colors (75)
Merge Sorted Array

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值