编程珠矶学习笔记(12)- 快速排序法1 O(nlogn)

18 篇文章 0 订阅

个人原创,转载请注明出处,谢谢!

一、目的

input: n个元素的数组;

output: n个元素的有序数组

constrain:使用快速排序法,数组有序,左小右大,O(nlogn)

二、算法原理

使用分治的思想来解决,使用递归的方法来实现,即将数组不断的剖分成小部分,然后对每一个小部分进行排序,每一个小部分的有序,最终使得整个数组有序。例如,假设现在有一个8元素的待排数组:

 

 qsort1 

 

可以看出经过一轮排序,有一批数已基本有序(左侧的小于某个元素,右侧的均于该元素),但插入法排序一次只能使一个元素就位。

三、代码

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

/* Data and supporting functions */

#define MAXN 10000000

 

typedef int DType;

 

DType realx[MAXN];

int *x = realx;       /* allow x to shift for heaps */

int n;

 

void swap(int i, int j)

{    

DType t = x[i];

       x[i] = x[j];

       x[j] = t;

}

 

int randint(int l, int u)

{    

return l + (RAND_MAX*rand() + rand()) % (u-l+1);

}

 

/* Simplest insertion sort */

void insert_sort()

{    

int i, j;

       for (i = 1; i < n; i++)

              for (j = i; j > 0 && x[j-1] > x[j]; j--)

                     swap(j-1, j);

}

 

/* Timing */

void timedriver()

{    

int i, mod, start, clicks;

       while (scanf("%d %d", &n, &mod) != EOF) {

              if (mod <= 0)

                     mod = 10*n;

              for (i = 0; i < n; i++)

                     x[i] = randint(0, mod-1);

              k = n/2;

              start = clock();

              isort1(); 

              clicks = clock() - start;

             

              printf("%d/t%d/t%d/t%g/n", n, mod, clicks,

                     1e9*clicks/((float) CLOCKS_PER_SEC*n));

       }

}

 

int main()

{    

timedriver();

       return 0;

}

四、代码注解

 

#include <stdio.h>

#include <stdlib.h>

#include <time.h>

 

/* Data and supporting functions */

#define MAXN 10000000

typedef int DType;

 

DType x[MAXN];

int *x = realx;

int n;

 

/*交换x[i]x[j]的值*/

void swap(int i, int j)

{    

DType t = x[i];

       x[i] = x[j];

       x[j] = t;

}

 

int randint(int l, int u)

{    

return l + (RAND_MAX*rand() + rand()) % (u-l+1);

}

 

/*快速排序法1 */

void qsort1(int l, int u)

{     int i, m;

       if (l >= u) { /*仅一个元素了返回即可*/

              return;

       }

       m = l;

       for (i = l+1; i <= u; i++)

              if (x[i] < x[l]) {

                     swap(++m, i);

}

}

/*这里是难点:交换它俩的原因是:本轮我们要把x[l]按照前面所说的算法原理进行移动,最终使得x[L]左则的小于x[L]x[L]右侧的大于x[L],大家可以发现比较循环是从L+1开始的,所以循环结束只有一个元素不满足条件,那就是x[L],因为它根本就没有移动,因此在这里我们要做一次交换,这样便可满足x[0]…<= x[L]  <= ….x[u],这里m姑且可做为最后x[L]应该在的位置,重要人物往往最后出现J*/

       swap(l, m);

       qsort1(l, m-1);

       qsort1(m+1, u);

}

 

/* 时间驱动函数,用于测试该算法性能*/

void timedriver()

{    

int i, mod, start, clicks;

 

       while (scanf("%d %d", &n, &mod) != EOF) {

              if (mod <= 0) {

                     mod = 10*n;

              }

              /*初始化数组*/

              for (i = 0; i < n; i++) {

                     x[i] = randint(0, mod-1);

}

              start = clock();

              qsort1 (0, n-1);

              clicks = clock() - start;

             

              printf("%d/t%d/t%d/t%g/n", n, mod, clicks,

                     1e9*clicks/((float) CLOCKS_PER_SEC*n));

       }

}

 

int main()

{    

  timedriver();

       return 0;

}

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值