交换排序(冒泡排序和快速排序)

学习时间2022.12.13

交换排序

基本概念

冒泡排序

基本概念来自菜鸟教程

  • 冒泡排序(Bubble Sort)也是一种简单直观的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢"浮"到数列的顶端。
  • 示意图
    冒泡排序

快速排序

基本概念来自菜鸟教程解学武数据结构与算法教程

  • 快速排序的基本思想是:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据比另一部分的所有数据要小,再按这种方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,使整个数据变成有序序列。
  • 示意图
    快速排序

代码实现

基本数据结构

typedef int ElemType;

typedef struct {
	ElemType* elem;//整型指针
	int TableLen;//动态数组元素个数
}SSTable;

基本函数实现

void ST_init(SSTable& ST, int len) {
	ST.TableLen = len;
	//ST.elem = (ElemType*)malloc(sizeof(ElemType) * ST.TableLen);
	ST.elem = (ElemType*)calloc(ST.TableLen, sizeof(ElemType));
	//初始化随机数发生器
	srand(time(NULL));
	//输出0-100的ST.TableLen个随机数
	for (int i = 0; i < ST.TableLen; i++)
	{
		ST.elem[i] = rand() % 100;
	}
}

void swap(ElemType& a, ElemType& b) {
	int temp;
	temp = a;
	a = b;
	b = temp;
}

void ST_print(SSTable ST) {
	for (int i = 0; i < ST.TableLen; i++) {
		printf("%3d", ST.elem[i]);
	}
	printf("\n");
}

冒泡排序和对应main函数

void BubbleSort(ElemType A[], int n) {
	int i, j, flag;
	for (i = 0; i < n - 1; i++)
	{
		flag = 0;
		for (j = n - 1; j > i; j--)
		{
			if (A[j - 1] > A[j])
			{
				swap(A[j - 1], A[j]);
				flag = 1;
			}
		}
		if (0 == flag)
		{
			break;
		}
	}
}

int main() {
	SSTable ST;
	ST_init(ST, 10);
	ElemType A[] = { 32,45,11,324,32,59,90,85,1,49 };
	//memcpy(ST.elem, A, sizeof(A));
	ST_print(ST);
	BubbleSort(ST.elem, 10);
	ST_print(ST);
}
  • 对memcpy(ST.elem, A, sizeof(A));的解释
    • 这是将数组元素复制到另一个数组的函数

快速排序和对应main函数

//使用最右边的值作为分割值
int Partition1(ElemType A[], int left, int right) {
	//k,i的具体含义可以看下方的图
	int k, i;
	k = left;
	for (i = left; i < right; i++)
	{
		if (A[right] > A[i])
		{
			swap(A[k], A[i]);
			k++;
		}
	}
	swap(A[k], A[right]);
	return k;
}

//使用最左边的值作为分割值
int Partition2(ElemType A[], int left, int right) {
	ElemType pivot = A[left];
	while (left < right)
	{
		while (left < right && A[right] > pivot)//该while循环让right指向的元素一直减,直到遇到比pivot小的元素
		{
			right--;
		}
		A[left] = A[right];//由于最左边值已经存在pivot,可以覆盖这个值
		while (left < right && A[left] <= pivot)//该while循环让left指向的元素一直加,直到遇到比pivot大的元素
		{
			left++;
		}
		A[right] = A[left];
	}
	A[left] = pivot;
	return left;
}
//递归实现快速排序
void QuickSort(ElemType A[], int low, int high) {
	//pivot是中枢的意思,在快排中pivotpos指我们选中的分割值。选择方法有很多,这里选择了数列的最后一个数
	if (low < high)
	{
		int pivotpos = Partition(A, low, high);
		QuickSort(A, low, pivotpos - 1);
		QuickSort(A, pivotpos + 1, high);
	}
}

int main() {
	SSTable ST;
	ST_init(ST, 10);
	ElemType A[] = { 32,45,11,324,32,59,90,85,1,49 };
	//memcpy(ST.elem, A, sizeof(A));
	ST_print(ST);
	Partition1(ST.elem, 0, 9);
	ST_print(ST);
	QuickSort(ST.elem, 0, 9);
	ST_print(ST);
}

快速排序示意图

posted @ 2022-12-16 14:54  ayubene  阅读(44)  评论(0编辑  收藏  举报