快速排序 归并排序 堆排序

本文详细介绍了使用C++编程语言实现快速排序、归并排序和堆排序这三种经典的排序算法。代码包括了每种排序算法的核心逻辑,如快速排序中的分区操作、归并排序的递归合并以及堆排序的构建和调整过程。这些排序算法在计算机科学中有着广泛的应用,是理解数据结构和算法的基础。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文基于C++完成实现了快速排序,归并排序,堆排序。
代码结构如下

-- quickSort 递归实现快速排序

-- mergeSort  递归实现归并排序
------ merge 实现两个有序数组的归并

-- heapSort  实现堆排序
------ heapify 实现从一个数组转化为堆
------ down 实现 调节以该顶点为根的堆

快速排序

    void quickSort(vector<int> & arr, int lo, int hi) {
        if (lo >= hi) return;
        int m = lo + rand()%(hi-lo+1), i = lo, j = hi;
        int p = arr[m];
        swap(arr[lo], arr[m]);
        while(i<j) {
            while (i < j &&  p <= arr[j) j--;
            if (i<j) arr[i]=arr[j], i++;
            while (i < j && arr[i] <= p) i++;
            if (i<j) arr[j]=arr[i], j--;
        }
        arr[i]=p;
        
        quickSort(arr, lo, i-1);
        quickSort(arr, i+1, hi);
        return;
    }
  1. 选取pivot点
  2. 找到pivot点的最终排序位置,即pivot点左边都小于等于pivot,右边都大于等于pivot;
  3. 迭代快速排序pivot左边的数组
  4. 迭代快速排序pivot右边的数组

注意 if(i<j)不可以少。注意边界条件。
完成

归并排序

    void mergeSort(vector<int> & arr, int low, int high) {
        if (low >= high) return;
        int mid = low + (high-low)/2;
        mergeSort(arr, low, mid);
        mergeSort(arr, mid+1,high);
        
        merge(arr, low, mid, high);
        return;
    }
    void merge(vector<int> & arr, int lo, int mi, int hi) {
        // [lo,mi] [mi+1,hi]
        vector<int> temp(hi-lo+1, 0);
        int l1 = lo, l2 = mi+1, tj = 0;
        while (l1 <= mi && l2 <= hi) {
            if (arr[l1] <= arr[l2]) {
                temp[tj++] = arr[l1++];
            } else {
                temp[tj++] = arr[l2++];
            }
        }
        while (l1 <= mi) temp[tj++]=arr[l1++];
        while (l2 <= hi) temp[tj++]=arr[l2++];
        tj = 0;
        for (int i=lo; i<=hi;i++) arr[i]=temp[tj++];
    }

归并排序的核心思想是二分,对原来的数组分为两个数组进行排序,最后归并两个有序数组。

  1. 对数组平均划分为两个区间
  2. 对两个区间分别进行归并排序
  3. 对上述两个已经排序的数组进行归并, 即 merge函数,实现对两个有序数组的归并。

堆排序

  1. 使一个数组构建一个大根堆,大小和数组同尺寸。heapify
  2. 弹出堆顶,即最大元素,放入arr[n-1]位置。将原来的arr[n-1]放入堆顶,即arr[0]。 swap
  3. 堆大小减小一个尺度,并从堆顶更新当前堆,维护大根堆的结构 ,down
  4. 弹出堆顶直至堆大小为1.

堆的思想则是维持半有序的结构,大根堆,即堆顶元素大于等于其他元素;小根堆,即堆顶元素小于等于其他元素。为了实现数组从小到大的排序,我们可以构建一个大根堆,每次弹出堆顶,放入数组的最后一个位置,减小堆的大小,然后更新当前堆,使其符合大根堆的结构。

    void heapSort(vector<int> & arr) {
        if (arr.size() <= 1) return;
        // 从小到大排序 所以是大根堆, 每次弹出将最大值放在最后一位, 堆空间缩小一个。
        heapify(arr); 
        int n = arr.size();
        for (int i = n-1; i>=1; i--) {
            swap(arr[0], arr[i]);
            
            down(arr, 0, i); //堆大小缩小一个位置
            
            
        }
        return;
    }
    void heapify(vector<int> & arr) {
        int k = arr.size(); 
        int lastNotLeaf = ((k-1)>>1);
        for (int i = lastNotLeaf; i>=0;--i) {
            down(arr, i, k);
        }
        return;
    }
    void down(vector<int> & arr, int pos, int k) {
        if (k <= 1) return;
        // 沿着当前节点不符合 大根堆  k代表堆的大小 前k个数据构成大根堆
        int _t = arr[pos]; 
        while (pos < k) {
            int r = (pos+1)<<1;
            int l = r-1;
            
            if (l >= k) break; // 这里判断不能出错!! 啊 后面判断r有没有出界 这里先判断l是否出界
            
            int _max = r>=k? l:( (arr[l]<arr[r])? r:l); // 大根堆 保留最大值
            if (arr[_max] <= _t) break; // 如果已经满足条件 就退出循环
            arr[pos] = arr[_max];
            pos = _max;
        } 
        arr[pos] = _t;
        return;
    }

完整代码

class Solution {
public:
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     * 将给定数组排序
     * @param arr int整型vector 待排序的数组
     * @return int整型vector
     */
    vector<int> MySort(vector<int>& arr) {
        // write code here
//         quickSort(arr, 0, arr.size()-1);
//         mergeSort(arr, 0, arr.size()-1);
        heapSort(arr);
        return arr;
    }
    void quickSort(vector<int> & arr, int lo, int hi) {
        if (lo >= hi) return;
        int m = lo + rand()%(hi-lo+1), i = lo, j = hi;
        int p = arr[m];
        swap(arr[lo], arr[m]);
        while(i<j) {
            while (i < j && arr[j] >= p) j--;
            if (i<j) arr[i]=arr[j], i++;
            while (i < j && arr[i] <= p) i++;
            if (i<j) arr[j]=arr[i], j--;
        }
        arr[i]=p;
        
        quickSort(arr, lo, i-1);
        quickSort(arr, i+1, hi);
        return;
    }
    void mergeSort(vector<int> & arr, int low, int high) {
        if (low >= high) return;
        int mid = low + (high-low)/2;
        mergeSort(arr, low, mid);
        mergeSort(arr, mid+1,high);
        
        merge(arr, low, mid, high);
        return;
    }
    void merge(vector<int> & arr, int lo, int mi, int hi) {
        // [lo,mi] [mi+1,hi]
        vector<int> temp(hi-lo+1, 0);
        int l1 = lo, l2 = mi+1