数据结构之排序算法(二)

在上一个博客里,说了一下插入类排序。今天和大家说一下交换类排序。交换类排序是一种基于交换的排序方法,主要介绍两种排序方法:冒泡排序(+改进)、快速排序

1、冒泡排序
冒泡排序是一种简单的交换类排序方法,能够将相邻的数据元素进行交换,从而逐步将待排序序列变成一个有序序列。基本思想是:从头到尾扫描待排序序列,再扫描过程中顺次比较相邻的两个元素的大小,判断是否进行交换操作

void bubbleSort1(int a[], int n) {
    int temp;
    for (int i = 0; i < n - 1; ++i) {
        for (int j = n - 1; j > i; --j) {
            // 比较大小,判断是否交换
            if (a[j - 1] > a[j]) {
                temp = a[j - 1];
                a[j - 1] = a[j];
                a[j] = temp;
            }
        }
        // 将每一遍排序过程打印出来
        printf("第%2d遍:", i + 1);
        printArray(a, n);
        printf("\n");
    }
}

对于上面的排序方法,和要排序的序列的混乱程度是没有关系的,因为无论什么时候已经排好序了,方法都会一直执行到最后。这显然是可以改进的,当已经是排好序的时候,就直接跳出循环结束方法了,所以在下面的改造中增加了标记,用来检测是否发生了交换;如果没有交换,则说明已经排好序了,直接退出。

void bubbleSort2(int a[], int n) {
    int flag = 0, temp;
    for (int i = 0; i < n - 1; ++i) {
        for (int j = n - 1; j > i; --j) {
            if (a[j - 1] > a[j]) {
                temp = a[j - 1];
                a[j - 1] = a[j];
                a[j] = temp;
                flag = 1;
            }
        }
        printf("第%2d遍:", i + 1);
        printArray(a, n);
        printf("\n");
        // 没有发生循环,直接跳出循环
        if (flag == 0)
            break;
        else
            flag = 0;
    }
}

2、快速排序
基本思想是:在待排序记录中选择一个元素作为基准,将小于它的元素放到它的左边,大于它的放到它的右边,然后对于这两个子序列在进行同样的操作,即利用递归方法

// 分割序列变成两个序列
int division(int a[], int left, int right) {
    int base = a[left];// base element
    // until the left cursor meet or exceed the right cursor
    while (left < right) {
        // find the first element smaller than base from right to left
        while (left < right && a[right] > base)
            --right;
        a[left] = a[right];
        // find the first element bigger than base from left to right
        while (left < right && a[left] < base)
            ++left;
        a[right] = a[left];
    }
    a[left] = base;
    // return the base element location
    return left;
}

void quickSort(int a[], int left, int right) {
    int i, j;
    if (left < right) {
        i = division(a, left, right);
        quickSort(a, left, i - 1);
        quickSort(a, i + 1, right);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值