【C语言】交换类排序之冒泡排序、快速排序分析及输出每趟排序的结果

本文详细介绍了冒泡排序和快速排序的原理,提供了完整的代码示例,并分析了它们的时间复杂度,包括最好、最坏和平均情况。
摘要由CSDN通过智能技术生成

目录

冒泡排序

快速排序

完整代码


冒泡排序

        思想:反复扫描待排序列,不断将相邻的记录两两比较,当遇到前后逆序的情况下则交换记录,每躺排序可以确定一个最大的记录在最后,至多需要进行n-1躺排序。如果某躺排序未发生交换代表已经有序,停止排序即可。冒泡排序在记录逆序时才交换,保证稳定性。

void BubbleSort(int arr[],int length){//冒泡排序
	int CHANGE=1;//改变标志位
	for(int i=1;CHANGE && i<length;i++){//对待排序列进行冒泡排序最多length-1躺
		CHANGE=0;
		for(int j=1;j<=length-i;j++){//逆序则交换
			if(arr[j]>arr[j+1]){
				int temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
				CHANGE=1;
			}
		}
		printf("第%d次冒泡排序的结果为:\n",i);
		PrintArr(arr,length);
	}
}

        时间复杂度:最好情况是待排记录已经从小到大顺序排列,仅仅进行一趟排序比较n-1次即可,不发生移动,最坏情况是待排序记录从大到小逆序排列,第i躺排序对比n-i次,移动3(n-i)次,总比较n-1+n-2+....+1=n(n-1)/2,总移动3n(n-1)/2,平均时间复杂度为T(n)=O(n^2)

快速排序

        思想:设置记录基准,从low->high对待排记录进行排序,经过一趟排序后基准将待排序列划分为两个子表,左部子表所有的记录均小于该基准,右部子表的记录均大于该基准,再对左部子表和右部子表进行排序。快速排序不稳定,例如:2,1,1

int QuickPass(int arr[],int low,int high){//对待排记录从low->high进行快速排序,返回基准位置
	static int nums=1;//记录执行次数
	int x=arr[low];//设置基准
	while(low<high){
		while(low<high && arr[high]>=x){//从high处开始,大于等于基准时指针向前移动
			high--;
		}
		if(low<high){//小于基准时移动记录
			arr[low]=arr[high];
			low++;
		}
		while(low<high && arr[low]<x){//再从low处开始,小于基准时指针向后移动
			low++;
		}
		if(low<high){//大于等于基准时移动记录
			arr[high]=arr[low];
			high--;
		}
	}
	arr[low]=x;
	printf("第%d次快速排序的结果为:\n",nums);
	PrintArr(arr,length);
	nums++;
	return low;//返回基准经过排序后位置
}
void QuickSort(int arr[],int low,int high){
	if(low<high){
		int pos=QuickPass(arr,low,high);
		QuickSort(arr,low,pos-1);
		QuickSort(arr,pos+1,high);
	}
}

        时间复杂度:快速排序的时间复杂度与递归的深度有关,在最好情况下,每一趟快速排序基准都正好将整个待排序列分为两个子表,基准在正中间,每趟的时间复杂度都不大于O(n),此时的递归深度为log2n+1,时间复杂度为T(n)=O(nlog2n)。最坏情况则是原本待排序列已经基本有序,在经过一趟快排后左部子表长度为0,右部子表为除基准外的n-1个记录,再不断对右部子表进行快速排序,此时的时间复杂度会退化为T(n)=O(n^2),平均的时间复杂度为T(n)=O(nlog2n)。

完整代码

#include<stdio.h>
void BubbleSort(int*,int);//冒泡排序
int QuickPass(int*,int,int);//一趟快排
void QuickSort(int*,int,int);//完整快排
void PrintArr(int*,int);//输出记录
int length;//全局变量记录数组长度
void BubbleSort(int arr[],int length){//冒泡排序
	int CHANGE=1;//改变标志位
	for(int i=1;CHANGE && i<length;i++){//对待排序列进行冒泡排序最多length-1躺
		CHANGE=0;
		for(int j=1;j<=length-i;j++){//逆序则交换
			if(arr[j]>arr[j+1]){
				int temp=arr[j];
				arr[j]=arr[j+1];
				arr[j+1]=temp;
				CHANGE=1;
			}
		}
		printf("第%d次冒泡排序的结果为:\n",i);
		PrintArr(arr,length);
	}
}
int QuickPass(int arr[],int low,int high){//对待排记录从low->high进行快速排序,返回基准位置
	static int nums=1;//记录执行次数
	int x=arr[low];//设置基准
	while(low<high){
		while(low<high && arr[high]>=x){//从high处开始,大于等于基准时指针向前移动
			high--;
		}
		if(low<high){//小于基准时移动记录
			arr[low]=arr[high];
			low++;
		}
		while(low<high && arr[low]<x){//再从low处开始,小于基准时指针向后移动
			low++;
		}
		if(low<high){//大于等于基准时移动记录
			arr[high]=arr[low];
			high--;
		}
	}
	arr[low]=x;
	printf("第%d次快速排序的结果为:\n",nums);
	PrintArr(arr,length);
	nums++;
	return low;//返回基准经过排序后位置
}
void QuickSort(int arr[],int low,int high){
	if(low<high){
		int pos=QuickPass(arr,low,high);
		QuickSort(arr,low,pos-1);
		QuickSort(arr,pos+1,high);
	}
}
void PrintArr(int arr[],int length){//输出记录序列
	for(int i=1;i<=length;i++){
			printf("%d ",arr[i]);
		}
	printf("\n");
}
int main(){
	int arr[]={00,55,88,66,33,99,44,77,11,22};
	length=sizeof(arr)/sizeof(arr[0])-1;
	printf("排序前为:\n");
	PrintArr(arr,length);
//	BubbleSort(arr,length);//冒泡排序
	QuickSort(arr,1,length);//快速排序
	printf("排序后为:\n");
	PrintArr(arr,length);
	return 0;
}

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值