冒泡排序的优化

传统的冒泡排序算法我们应该很熟悉,主要的原理是:

1.比较相邻的元素。如果第一个比第二个大,就交换他们两个。

2.对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。

3.针对所有的元素重复以上的步骤,除了最后一个。

4.持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

但是此种方法每一趟循环只能找到一个最大或者最小的值,效率低,基于这个缺点,我们可以利用在每一趟排序中进行正向

和反向两遍冒泡的方法,一次可以得到两个值,最大值和最小值,确定两个值的位置这样我们的循环次数就减少了一半。

直接上代码吧:

void bubble_sort_test(){
	
	int arr[] = { 5, 6, 8, 3, 9, 2, 7, 0, 4, 1 };
	int sz = sizeof(arr)/sizeof(arr[0]);
	for (int i = 0; i < sz/2; i++){
		//正向循环 把最大这下沉到 j+1的位置
		for (int j = i; j< sz - i - 1; j++){
			//前一个数大于后一个   下沉
			if (arr[j]>arr[j + 1]){
				int tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
			}
		}
		//反向循环 把最小者上冒的i的位置。
		for (int j = sz-1; j>i; j--){
			// 后一个数比前一个数小   上冒 
			if (arr[j]<arr[j - 1]){
				int tmp = arr[j];
				arr[j] = arr[j - 1];
				arr[j - 1] = tmp;
			}
		}
	}
	int i = 0;
	for (i = 0; i < sz; i++){
		printf("%d ", arr[i]);
	}
}

int main(){

	bubble_sort_test();
	getchar();
	return 0;
}

 

还有一种情况,如果给出的数组中已经有大量已经排序好的数据,那么按照原始方法我们还是要跑n-1趟,这是挺浪费时间的。

于是可以这样,我们每跑完一趟就判断一次原数组是否有序,如果有序就结束。

所以就有了一个标志位flag来助我们判断。

首先来看看分析:

话不多说,代码才是硬道理:

void bubble_sort(int arr[], int sz)
{
	int i = 0;
	int j = 0;

	for (i = 0; i < sz - 1; i++)
	{
		int flag = 1;//假定每次进入都是有序的 flag为1;
		for (j = 0; j < sz - i - 1; j++){
			int tmp = 0;
			if (arr[j] > arr[j + 1]){
				tmp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = tmp;
				flag = 0;//如果发生交换,则flag 置为0;
			}
		}
		if (flag == 1)//如果这趟走完,没有发生交换,则原数组有序;
			break;
	}
}

如果有兴趣,可以将上下两个代码合二为一,就是最终我能想到的优化了。

发布了78 篇原创文章 · 获赞 34 · 访问量 4万+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章