C语言实现快速排序

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define MAX_NUM 100
#define NUMS_LEN 20

/**
 * 打印数组
 * @param nums 数组指针
 * @param len 数组长度
 */
void printNums(int *nums, int len) {
    for (int i = 0; i < len; i++) {
        printf("%d ", nums[i]);
    }
    printf("\n");
}

/**
 * 生成随机数
 * @return 返回一个数组指针
 */
int *randNums(int len, int maxNum) {
    // 重置种子,不然每次生成的随机数是一样的
    srand((unsigned) time(NULL));
    int *nums = (int *) malloc(sizeof(int) * len);
    for (int i = 0; i < len; i++) {
        int randNum = rand() % maxNum;
        nums[i] = randNum;
    }
    printf("生成随机数:");
    printNums(nums, len);

    return nums;
}

/**
 * 分区
 * @param nums 数组
 * @param left 左指针
 * @param right 右指针
 * @param axis 轴指针
 * @return 返回左指针向右移动的步数
 */
int partitionExchange(int *nums, int *left, int *right, int *axis) {

    int leftStep = 0;// 记录左指针移动的步数

    while (1) {
        // 左指针和轴进行比较
        while (1) {
            if (*left <= *axis) {
                // 如果左指针比轴要小,则左指针向又移动一格
                if (left <= right) {
                    left += 1;
                    leftStep++;
                } else {
                    // 已经顶到最右边了
                    break;
                }

            } else {
                // 如果左指针并不比轴小,则停止移动左指针
                break;
            }
        }


        // 启动右指针,比较右指针和轴的大小
        while (1) {
            if (*right >= *axis) {
                // 如果右指针比轴大,则右指针向左移
                if (right >= left) {
                    right -= 1;
                } else {
                    // 已经顶到最左边了
                    break;
                }

            } else {
                // 如果右指针并不比轴大,则停止右指针
                break;
            }
        }


        // 如果左指针仍然在右指针的右边,则交换两个指针的位置的值
        if (left < right) {
            // 交换左指针和右指针的值
            int temp = *left;
            *left = *right;
            *right = temp;
            continue;
        } else {
            // 如果左指针和有指针重合,则无需再移动指针了, 将左指针的值和轴进行互换
            int t = *axis;
            *axis = *left;
            *left = t;
            break;
        }
    }
    return leftStep;

}

/**
 * 快速排序,Quicksort, 也被成为:partition-exchange sort
 * @param nums 数组
 * @param len 数组长度
 */
void partitionExchangeSort(int *nums, int len) {

    if (len < 2) {
        printf("数组元素小于2个,无需排序\n");
        return;
    }


    // 每次选取数组的最后一个元素作为轴
    int *axis = &nums[len - 1];
    // 定义两个指针,分别指向排除轴元素之后,数组的最左和最右的元素
    int *left = &nums[0];
    int *right = &nums[len - 2];

    int leftStep = partitionExchange(nums, left, right, axis);


    // 左边数组为:0 到 leftStep-1
    if (leftStep > 1) {
        partitionExchangeSort(nums, leftStep);
    }


    // 右边数组为:leftStep+1 到 len-1
    if (len - leftStep - 1 > 1) {
        partitionExchangeSort(&nums[leftStep + 1], len - leftStep - 1);
    }

}

/**
 * 判断数组是否是排列好的升序
 * @param nums 数组
 * @param len 数组长度
 * @return
 */
int isAsc(const int *nums, int len) {
    for (int i = 0; i < len - 1; i++) {
        if (nums[i] > nums[i + 1]) {
            return 0;
        }
    }

    return 1;
}

int main() {

    int *nums;
    int i = 0;// 去检验10000次
    while (i++ < 10000) {
        nums = randNums(NUMS_LEN, MAX_NUM);
        partitionExchangeSort(nums, NUMS_LEN);
        printf("排序完之后:");
        printNums(nums, NUMS_LEN);

        if (isAsc(nums, NUMS_LEN)) {
            printf("第 %d 次测试成功\n", i);
        } else {
            printf("第 %d 次测试失败\n", i);
            break;
        }
        printf("====================\n\n");
    }
    free(nums);

    return 0;
}

运行:

gcc main.c
./a.out

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值