您的位置:首页 > 其它

各种排序方法源码及复杂度分析(二)

2014-07-30 21:48 204 查看

八、快速排序

快速排序是一个神奇的算法,他采用了递归的算法,找到数列的第一个数,整个数列比他小的数放在他的左边,比他大的数放在他的右边,实现逻辑是:把数列的第一个数当做一个标志mark,然后接下来的每个数都和他比较大小,如果小不移动,如果比mark大,则和第一个比mark大的数交换位置。这里用到了双指针,一个指针指向循环的数组下标,一个指针指向比mark小的所有数的最后一位,只要第一个指针指向的数的值大于mark的值,那么第二个指针加一,第一个指针指向的数和第二个指针指向的数交换位置。
代码实现如下:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int partition(int *data, int begin, int end) {
int mark = data[begin];
int i = 0, k = begin;
int tmp;
for (i = begin + 1; i <= end; i++) {
if (data[i] <= mark) {
k++;
if (k < i) {
tmp = data[k];
data[k] = data[i];
data[i] = tmp;
}
}
}
tmp = data[begin];
data[begin] = data[k];
data[k] = tmp;
return k;
}

//快速排序
void QuickSort(int *data, int begin, int end) {
int ret;
if (begin < end) {
ret = partition(data, begin, end);
QuickSort(data, begin, ret - 1);
QuickSort(data, ret + 1, end);
}
}

int main(void) {
int data[] = { 70, 4, 8, 23, 5, 7, 9, 1, 4, 65, 23, 456, 67, 13, 24, 4656,
352, 79, 278, 41 };
int i;
int length = sizeof(data) / sizeof(int);
QuickSort(data, 0, length - 1);
for (i = 0; i < length; i++) {
printf("%d ", data[i]);
}
return 0;
}
复杂度分析:
最差复杂度是n^2,最优的复杂度是n*lg(n),平均的复杂度是n*lg(n),如何确保他的复杂度总是n*lg(n)呢?有两种方法,一种是随机排序序列中的元素,另外一种是随机选择主元,这种方法称为“随机化快速排序”。“随机化快速排序的优点是:无需对输入序列的分布做任何假设
C语言中Static关键字大体有三个作用:
1. static具有隐藏的作用,举个例子,如果在a.c文件中写了一个msg()函数以及定义了一个变量a,在另外一个main.c函数中可以调用msg函数,也可以引用变量a,为什么呢?是因为这个msg()函数和变量a没有被隐藏,main.c文件可以找到他们,如果是static msg() 或者static a,这样main.c就找不到他了,msg()函数和变量a只能在a.c文件中被调用。
2. 保持变量内容的持久,存储在静态区的数据会在程序第一次运行的时候完成初始化,也是唯一的初始化。利用这个性质可以计算一个函数被调用的次数。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void count() {
static int num = 0;
num++;
printf(" I have been called %d timesn\n", num);
}
int main() {
int i;
for (i = 1; i <= 3; i++) {
count();
}
return 0;
}
打印结果是:
I have been called 1 timesn
I have been called 2 timesn
I have been called 3 timesn

3. static变量默认初始化为0,保存在静态数据区,静态数据区变量默认都是0,某些时候这个特性可以减少程序员的工作量。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: