数据结构(排序篇)------交换排序 实现:冒泡 & 快排

冒泡排序
note:排序部分用两层循环,外层控制排序次数,内层控制排序时的交换。需注意内层循环的终止位置。经过i次排序后,数组的后i个数字是有序的。所以发生最后一次交换的两个数字应该是 i 前的两个数字a[j] 和 a[j+1],此时j = length - i - 1。

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void Swap(int a[], int j);//交换元素
void PutNums(int a[], int length); //输出数组
void BubbleSort(int a[], int length);//冒泡排序
void CreatRandomNum(int a[], int length);//生成随机数序列

int main() {
	int a[10] = {0};
	int length = sizeof(a) / sizeof(a[0]);
	CreatRandomNum(a, length);
	printf("待排序数组为:");
	PutNums(a, length);
	printf("\n");
	BubbleSort(a, length);
	printf("排序后数组为:");
	PutNums(a, length);
}

void BubbleSort(int a[], int length) {
	for (int i = 0; i < length - 1; i++) { //n个元素,最多经过n-1趟完成排序。
		int flag =  0;//若某次排序并没有发生交换,则说明数组已有序。
		for (int j = 0; j < length - i - 1; j++) { //经过i趟排序后,数组的后i个数字已经有序。
			if (a[j] > a[j + 1]) {//判断条件是大于,所以冒泡排序是稳定的
				Swap(a, j);
				flag = 1;
			}
		}
		if (!flag)
			break;
	}
}

void Swap(int a[], int j) {
	int index = a[j];
	a[j] = a[j + 1];
	a[j + 1] = index;
}

void CreatRandomNum(int a[], int length) {
	srand(time(0));
	for (int i = 0; i < length; i++)
		a[i] = rand() % 100 + 1;
}

void PutNums(int a[], int length) {
	for (int i = 0; i < length; i++)
		printf("%d ", a[i]);
}


在这里插入图片描述

快速排序
note:

  1. 在将数组划分为两个子表的过程中,low和high交替扫描数组时,是high先开始扫描.
  2. a[high] 与 a[low] 的比较是大于等于或小于等于,若不带等于号,在碰到a[i] == pivot时会陷入死循环,建议手动模拟一下如:{8,16,8,7,33,9},在第一轮中pivot为8(第一个8)上述数组第一轮变化过程为:
    1. high从后向前扫描碰到7(7小于8)将7写到low指向的地方(即数组开头的位置 位置0) 数组变为{7,16,8,7,33,9}此时low指向第一个7,high指向第二个7。
    2. low向后扫描碰到16(16>8)将16写到high指向的位置,数组变为{7,16,8,16,33,9},此时low指向第一个16,high指向第二个16。
    3. high向前扫描碰到8,若判断条件中没有 “=” ,则跳出循环,并将8写到low所指向的地方,数组变为{7,8,8,16,33,9}。此时low指向第一个8,high指向第二个8.
    4. low向后扫描,若判断条件中没有 ”=“ ,则跳出循环,将第一个8 写到high指向的位置,则程序进入死循环。
  3. 设有相同数字且均小于基准元素pivot时,则数字都会被交换到左区间,显然两数字的相对位置会发生变化,所以快排不稳定。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void PutNums(int a[], int length);//输出数组
void CreatRandomNum(int a[], int length); //生成随机数序列
void QuickSort(int a[], int low, int high);//快速排序
int Partition(int a[], int low, int high);//将数组分为两个子表
int main() {
	int a[10] = {0};
	int length = sizeof(a) / sizeof(a[0]);
	CreatRandomNum(a, length);
	printf("待排序数组为:");
	PutNums(a, length);
	QuickSort(a, 0, length - 1);
	printf("\n排序后数组为:");
	PutNums(a, length);
}

void QuickSort(int a[], int low, int high) {
	if (low < high) {
		int pivot = Partition(a, low, high);
		QuickSort(a, low, pivot - 1);
		QuickSort(a, pivot + 1, high);
	}
}

int Partition(int a[], int low, int high) {
	int index = a[low];
	while (low < high) {
		while (a[high] >= index && high > low)
			high--;
		a[low] = a[high];
		while (a[low] <= index && low < high)
			low++;
		a[high] = a[low];
	}
	a[low] = index;
	return low;
}


void CreatRandomNum(int a[], int length) {
	srand(time(0));
	for (int i = 0; i < length; i++)
		a[i] = rand() % 100 + 1;
}

void PutNums(int a[], int length) {
	for (int i = 0; i < length; i++)
		printf("%d ", a[i]);
}

对有相同数字的序列进行排序如下图所示。

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值