基于冒泡排序的增强型算法

基于冒泡排序的增强型算法

 今天,闲来无事,用c语言来写一个排序算法。在写算法的时候,首先想到的就是最简单的排序算法-冒泡排序算法。算法很简单,几行代码就完成了。但在完成之后,从该算法本身考虑是否可以节省效率的实现呢?

        首先看一下冒泡排序的最基础的代码实现。

void bubbleSort(char *name[], int n) {
	char *tmp;
	int i, j;
	for (i = 0; i < n; i++) {
		for (j = n - 1; j > i; j--) {
			if (strcmp(name[j - 1], name[j]) > 0) {
				tmp = name[j - 1];
				name[j - 1] = name[j];
				name[j] = tmp;
			}
		}
	}
}

         针对代码,首先分析了算法的实现的细节。该算法在实现过程中,如果中间的一次循环中,一次交换都没有发生,则进行下一个循环。而仔细分析,我们可以知道,如果在一次循环排序中,没有发生任何的元素的互换,则说明该排序数组已经排好序,那么,算法即算执行完毕。针对这种情况,我们是否可以对算法进行调优呢?

         既然是考虑是否有元素互换,那么,我们可以在元素互换的操作中,增加标示来实现我们希望的这种想法。代码如下:

void bubbleSort(char *name[], int n) {
	char *tmp;
	int i, j;
	for (i = 0; i < n; i++) {
		int flag = 0;
		for (j = n - 1; j > i; j--) {
			if (strcmp(name[j - 1], name[j]) > 0) {
				tmp = name[j - 1];
				name[j - 1] = name[j];
				name[j] = tmp;
				flag = 1;
			}
		}
		if (!flag) break;
	}
}


         在这里,我不去做太多数学上的分析,大家可以分析一下。

 到这里,感觉该算法还是有缺陷。缺陷在哪里呢?冒泡排序中(假设是从小到大的排序),我们的目标是将小的放到最前面,大的放在最后面。而在冒泡算法中,只是单一的去做了小元素的查找和前移,而对于较大的数据,就不去理会。而在我们的算法中,没循环一次,都需要耗费一定的时间效率,而如果在每一次的循环中,除了将小的元素往前移,而同时找出剩下元素中最大的一个放在数组的后面去呢?这样,我们可以节省不少的时间开销,提升了算法的效率。

基于上面的想法,在循环中同时对小的数据往前排,而大的数据也找出来,将其排到后面。具体的算法描述:

1、从数组的最后一个元素(i)开始,比较其同前面的一个元素(i-1)的大小,如果最后一个元素要比其前面的一个元素小,则同前一个元素交换位置(用i表示元素的位置),并用一个标示来表示进行过排序。

2、同时,我们假定最后一个元素是最大的。并且,将该最大的元素做出标示,表示其目前是最大的元素(用k标示该最大元素的位置)。将该元素同位置为i的元素进行比较。因为在1步中,已经对元素进行了比较,可以知道,在i位置的元素一定大于i-1位置的元素。如果k位置的元素要小于i位置的元素,则进行交换,并用一个标示来表示进行过元素的交换。

3、一轮完成之后,最小的元素将会排到数组的最前面,而最大的元素排在最后面。所以,在进行下一轮的排序时,次小的元素的位置需要向后移位,而次大的元素位置需要向前移动一位。

4、当次小值的位置大于或等于次大值的位置时,退出排序。

上述的算法描述得不是非常清晰,根据上面的算法描述,提供具体的算法实现供参考:

void bubbleSort(char *name[], int n) {
	char *tmp;
	int i, j, k,cFlag;
	int circle = 0;
	cFlag = 0;
	k = n - 1;
	for (i = 0; i < n; i++) {
		int flag = 0;
		cFlag = 0;
		for (j = k; j > i ; j--) {
			if (strcmp(name[j - 1], name[j]) > 0) {
				tmp = name[j - 1];
				name[j - 1] = name[j];
				name[j] = tmp;
				flag = 1;
			}
			if (strcmp(name[j], name[k]) > 0) {
				tmp = name[j];
				name[j] = name[k];
				name[k] = tmp;
				cFlag = 1;
			}
		}
		if(cFlag==1){
			k = k-1;
		}
		if (!flag)
					break;
		}
}


经过上面的一个改造,对冒泡排序中所能做的改进也想不出更优的算法了。

上面提出的这些算法,仅供参考。而对于改造算法的想法,只是出于对算法效率提升的角度来考虑,希望能够对现有算法的实现进行相应的调整和提高,以便可以得到更优的算法实现。同时,也是提醒自己,可以通过该示例,举一反三,为工作中所遇到的问题,多一些想法,就可以获得多一些解决途径。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值