数组排序--C++复习--钱能-第3版

本文详细介绍了三种常见的排序算法:冒泡排序、直接插入排序和快速排序。冒泡排序通过相邻元素比较交换实现排序,改进版减少了不必要的比较。直接插入排序通过将元素逐个插入已排序序列实现排序。快速排序利用分治策略,选取枢轴元素将序列分为两部分。文章提供了每种排序算法的代码实现及运行结果,并分析了它们的时间复杂度。
摘要由CSDN通过智能技术生成

这里不写书面的官方的话语,均是我个人的理解。


列举三种排序:冒泡排序直接插入排序快速排序

10个元素从小到大排序,待排序数组为:

	int arr[]={55,2,6,4,32,12,9,73,26,37};

	int len = sizeof(arr)/sizeof(int);	 // 计算长度

 冒泡排序(改进版)

算法思想:简单来说,从前往后逐个比较相邻元素,保证后一个元素比前一个元素大。每一轮都选出了一个当前待排序元素中的最大值置于底部(数组末端),且这就是该元素的最终位置。每经过一轮,就确定一个元素的位置,所以待排序元素个数就减1。第i轮中,要在待排序的n-(i-1)个元素中选一个最大值。n个元素,至多需要n-1轮比较。

改进之处,就是增加一个flag变量,用来标记该轮是否发生元素交换。若没有发生,表示每一个元素都比前一个元素大,则排序完成。

void bubble(int arr[], int len){
	int flag = 1;
	for(int times = len-1; times > 0; times--){
		for(int i = 0; i<times; i++){
			if(arr[i]>arr[i+1]){
				int temp = arr[i]; 
				arr[i] = arr[i+1];
				arr[i+1] = temp;
				flag = 0;
			}
		} 		

		for(int i =0; i<len; i++){		// 输出每一趟的排序结果 
			cout<<arr[i]<<",";
		}
		cout<<endl;

		if(flag)
			return;
		else
			flag = 1;
	} 
}

改进的效果:对于本文所设数组来说,如果不改进,10个元素需要比较9轮。改进后仅需4轮。

运行结果如下 :

直接插入排序

算法思想:该算法运行过程中,会使待插入元素的左侧为有序序列。第一个元素已有序,因此直接从第二个元素开始“插入”操作。待插元素ins与左侧元素a[i]从右向左逐个比较,当a[i]大于ins时,a[i]后挪(注意不是交换);直至a[i]<ins,即确定ins的位置。

void insert(int a[],int len){
	// 待插元素不断与左侧元素比较,待插元素较小则交换 
	for(int i =1; i<len; i++){
        // index指向待插入元素左侧紧邻的元素
		int index = i-1,ins = a[i];
		for(; index >= 0 && a[index] > ins; index--){	// 将i之前的元素逐个与a[i]进行比较
            // 一定要注意for循环的终止条件 
			a[index+1] = a[index];	// 把大元素a[index]后挪一个位置 
		} 
		a[index+1] = ins;	// 插入 
		
		for(int i =0; i<len; i++){	// 输出每一趟的排序结果 
			cout<<a[i]<<",";
		}
		cout<<endl;
	}
}

运行结果如下 :

注:“|” 左侧为已排序列

快速排序

算法思想:采用分治思想,选定一个枢轴元素为基准,比他小的元素放在左侧,比它大的元素放在右侧。因此,每一趟都至少能确定所选枢轴元素在序列中的最终位置。

这里贴一个助于理解的表:

注:图自王道的《2022年数据结构考研复习指导》

代码实现如下:

void quick(int a[],int low, int high){
	int pivot = a[low]; 	// 取第一个元素为枢轴元素 
	int i=low, j = high;	// 两个指针 
	while(i<j){				// 通过指针移动,将元素从两端逐个与枢轴元素比较 
		while(a[j] >= pivot && i<j)  j--;
		a[i] = a[j];	// 从右侧找到第一个小于枢轴元素的元素,放至左侧 
		while(a[i] <= pivot && i<j)  i++;
		a[j] = a[i];	// 从左侧找到第一个大于枢轴元素的元素,放至右侧 
	}
	a[i] = pivot;           // 此时i=j,将枢轴元素放入序列
    // 递归调用,对左右两个子序列再进行划分,直至每个子序列内只有一个元素或空为止
	if(i-low > 1 || high - i > 1){    
		quick(a,low,i);
		quick(a,i+1,high);
	}	
}

运行结果如下 : 

 

 时空复杂度:

分析过程全网都有(想看分析过程请留言),在这直接贴结果:

   注:图自王道的《2022年数据结构考研复习指导》
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值