C实现快速排序

快速排序算法概述

  • 快速排序是采用一种分治的策略;
  • 对输入的无序序列选择一个基准数,然后将比基准数小的放在左边(序列A),比基准数大的放在右边(序列B)(假设现在排序要求升序排列);
  • 然后对序列A和序列B分别再做为第二步的输入序列,重复第二步;
  • 递归操作上面两步,直到输入序列只剩下一个元素返回,这样整个原始序列就已经变为有序序列;
  • 快速排序的平均时间算法复杂度为O(nlogn),最差的情况下时间复杂度为O(n^2)(当每次选择的基准数都是当前序列最大或者最小的数时);

C算法实现

volatile static unsigned count = 0;
static void quickSort(int *baseAddr, unsigned startIDX, unsigned endIDX)
{
    int tmp = 0;
    int benchData = baseAddr[startIDX];

    if(!baseAddr)
    {
        printf("The pointer can not be NULL!\n");
        return;
    }
    //判断输入序列是否只有一个元素,该条件为递归的结束条件
    if(startIDX >= endIDX)
    {
        return;
    }

    //每次选择输入序列的第一个元素为基准数;所以从第二个数开始与第一个数比较;
    int i = startIDX+1;
    int j = endIDX;

    while(i<j)
    {
        count++;//复杂度计数
        //如果元素i大于基准数,则将该元素跟序列末尾元素j交换位置,j--;
        //并且因为当前i已经发生变化,所以不用i++,下一次循环再比较i跟j的值;
        //如果元素i小于等于基准数,则i++,继续下一轮循环;
        //当i==j时,退出循环;
        if(baseAddr[i] > benchData)
        {
            tmp = baseAddr[i];
            baseAddr[i] = baseAddr[j];
            baseAddr[j] = tmp;
            j--;
        }
        else
            i++;
    }

    //因为在最后一次退出循环前有i++操作,i可能已经自增为应该放在基准数右边元素的序号;
    if(baseAddr[i] >= benchData)
        i--;

    //交换i元素和序列第一个元素(基准数);因为基准数肯定是>=i元素的;
    baseAddr[startIDX] = baseAddr[i];
    baseAddr[i] = benchData;

    //对序列的左半部分继续做排序;
    quickSort(baseAddr , startIDX, i);
    //对序列的右半部分继续做排序;
    quickSort(baseAddr , j, endIDX);

    return;
}

测试函数如下:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>

#define ARRAYLEN 1000
#define true 1
#define false 0
typedef unsigned short bool;

//序列是否为升序排列
static bool isAscendingOrder(int *baseAddr, unsigned dataLength)
{
    unsigned i = 0;
    do
    {
        if(baseAddr[i]>baseAddr[i+1])
        {
            //printf("The arrray is not ascending order!\n");
            return false;
        }

        i++;
    }while(i<(dataLength-1));

    //printf("The arrray is ascending order!\n");
    return true;
}

//序列是否为降序排列
static bool isDescendingOrder(int *baseAddr, unsigned dataLength)
{
    unsigned i = 0;
    do
    {
        if(baseAddr[i]<baseAddr[i+1])
        {
        //  printf("The arrray is not descending order!\n");
            return false;
        }

        i++;
    }while(i<(dataLength-1));

    //printf("The arrray is  descending order!\n");
    return true;
}

int ArrayData[ARRAYLEN] = {};
int main(int argc, char *argv[])
{
    //打开linux下的随机数产生设备;
    int randFD = open("/dev/urandom", O_RDONLY);
    if(randFD <= 0)
    {
        printf("open the urandom device failed!\n");
        return -1;
    }

    unsigned i = 0;
    for(;i<ARRAYLEN;i++)
    {
        read(randFD, ArrayData+i, sizeof(int));
        printf("%d  ", ArrayData[i]);
        if((i+1) %10 == 0)
            printf("\n");
    }
    close(randFD);

    //对产生的随机序列做快速排序;
    quickSort(ArrayData, 0, ARRAYLEN-1);
    //检查序列是否已经有序;
    if(isAscendingOrder(ArrayData, ARRAYLEN))
    {
        printf("The array is ascending order!\n");
    }
    else if(isDescendingOrder(ArrayData, ARRAYLEN))
    {
        printf("The array is descending order!\n");
    }
    else
    {
        printf("The array is unordered!\n");
    }

    printf("The operation count is:%u\n", count);

    return 0;
}

然后编译执行:

gcc quickSort.c -o quickSort -Wall
./quickSort

猜你喜欢

转载自blog.csdn.net/zyj_zhouyongjun183/article/details/79624576