RodneyX

博客园 首页 新随笔 联系 订阅 管理

交换排序的基本思想:

每次比较无序表L[0...n-1]中相邻两个元素大小,若为逆序则交换

一般常见的交换排序有两个,一个冒泡排序(非常简单),一个是快速排序(内部排序平均效率最好的排序算法)

冒泡排序的基本思想:

  1. 从前往后,每次比较无序表L[0...n-1]中相邻两个元素大小,若为逆序则交换

  2. 以结果为非递减序列为例,每次从前往后对1.中操作进行一轮,则会有一个无序表中的最大值到达最终位置上,因此只需要执行执行n-1次操作1.,并且某次执行若未发生元素交换则表明表已经有序排序完毕

于是有如下实现

void bubble_Sort(int A[], int length)
{
    for (int i = 1; i < length; ++i)
    {
        int flag = 0;
        for (int j = 0; j < length - i; ++j)  // 升序下每趟排序待排序序列中的最大的值会在最终位置上,故j < length - i
        {
            if (A[j] > A[j + 1])
            {
                int swap_val = A[j];
                A[j] = A[j + 1];
                A[j + 1] = swap_val;
                flag = 1;
            }
        }
        if (!flag) // 未发生交换则已经排序完毕
            return;
    }
}

快速排序的基本思想:

  1. 对表L[0...n-1],每次选择一个表中一个元素作为枢轴(pivot),然后将比pivot小的元素置于pivot元素在表最终位置的左边(以非递减的排序结果为例),比pivot大的元素置于pivot元素在表最终位置的右边(这是快速排序的精髓)

  2. 经过1.后,记pivot最终的索引为lo,表被划分为L[0...i-1]和``L[i+1...n-1],对这两个无序表递归执行1.,直到递归到无序表长为小于等于1,则此时有序,完成排序

对于1.,常用的实现方式是选择表头元素作为枢轴,并设lo = 表头元素的索引hi = 表位元素的索引

然后从hi开始,如果hi所指元素小于lo,将这个元素移动到lo所指向的位置,反之hi递减

对于lo的操作类似,只是和hi的操作相反即可,并且让hilo的移动交替进行,当hi == lo时这个位置就是pivot的最终位置

于是我们有如下实现

// cannot be called by user
int _partition(int A[], int lo, int hi)
{
    int pivot = A[lo];
    while (lo < hi)
    {
        while (lo < hi && A[hi] >= pivot)  // 不能采用严格不等号,也就是说相等也移动,否则死循环
            --hi;
        A[lo] = A[hi];
        while (lo < hi && A[lo] <= pivot)
            ++lo;
        A[hi] = A[lo];
    }
    A[lo] = pivot;
    return lo;
}

void quick_Sort(int A[], int length)  //这个函数建议按教材来实现,我这个可读性稍差
{
    if (length <= 1) // 终止条件
        return;
    int pivot = _partition(A, 0, length - 1);
    quick_Sort(A, pivot);
    quick_Sort(A + pivot + 1, length - pivot - 1);
}
posted on 2025-07-26 15:33  RodneyX  阅读(10)  评论(0)    收藏  举报