数据结构 排序 不稳定排序

非稳定排序:选择排序、快速排序

如果有两个数字的数值大小相同,排序后的相对顺序为被改变。

一.选择排序

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 


猜你喜欢

转载自blog.csdn.net/qq_38362049/article/details/81069831