非稳定排序:选择排序、快速排序
如果有两个数字的数值大小相同,排序后的相对顺序为被改变。
一.选择排序
1.将数组分成【已排序区】和【待排序区】
2.每一轮从【待排序区】中选择一个最小的元素放到【已排序区】的尾部
3.直到【待排序区】没有元素为止
二.快速排序
快速排序和归并排序的区别:快:【先处理当前的大问题 再分治】归:【先分治再递归】
坏时间复杂度:n^2
好时间复杂度:nlog(n)
1.先从数列中取出一个数作为基准数。
2.分区过程,将比这个数大的数全放到它的右边,小于或等于它的数全放到它的左边。
3.再对左右区间重复第二步,直到各区间只有一个数。(快速排序)
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#define swap(a,b){ \
__typeof(a) __temp = a; \
a = b; b = __temp; \
}
void select_sort(int *num, int n){
for(int i = 0; i < n - 1; i++){//将num[0]看作已排序区,排序n-1轮;
int ind = i;//ind用于记录待排序区最小数值的数组下标;
for(int j = i + 1; j < n; j++){
if(num[j] < num[ind]) ind = j;
}
swap(num[i], num[ind]);//每循环一轮找到最小值后,与num[i]交换;
}
return ;
}
void quick_sort(int *num, int l, int r){
if(l >= r) return ;
int head = l, tail = r, mid = num[l];//头指针;尾指针;基数存放;
while(head < tail){//头尾指针不重合时,继续遍历;
while(head < tail && num[tail] >= mid) tail--;//头尾指针不重合且右半部分比基数大;
if(head < tail) num[head] = num[tail]; head++;//跳出while循环,表示在右端找到了一个比基数小的数,给它换到左端;头指针后移
while(head < tail && num[head] <= mid) head++;//头指针不重合且左半部分比基数小;
if(head < tail) num[tail] = num[head]; tail--;//跳出上层while循环,把它换到右端;尾指针后移;
}
num[head] = mid;
quick_sort(num, l, head - 1);
quick_sort(num, head + 1, r);
return ;
}
#define TEST(n, func){ \
int *num = (int *)malloc(sizeof(int) * n); \
for(int i = 0; i < n; i++){ \
num[i] = rand() % 100; \
}\
func; \
printf("%s : ", #func); \
for(int i = 0; i < n; i++){ \
printf("%d ", num[i]); \
} \
printf("\n"); \
}
int main(){
srand(time(0));
TEST(20, select_sort(num, 20));
TEST(20, quick_sort(num, 0, 19));
return 0;
}
输出结果:
select_sort(num, 20) : 0 3 11 17 21 22 23 23 28 34 35 36 45 61 66 70 87 87 90 99
quick_sort(num, 0, 19) : 0 0 15 22 27 32 48 48 48 54 54 54 60 76 81 81 81 93 93 94