鸡尾酒排序(冒泡排序最终版)

鸡尾酒排序,又称冒泡排序的升级版,每轮遍历找出最大值和最小值。适合接近有序的数组。文章探讨了两种优化策略:当内层循环无交换时提前结束,以及通过边界下标减少循环次数。同时指出仍有优化空间,特别是调整初始值以进一步提升效率。
摘要由CSDN通过智能技术生成

鸡尾酒排序:每一轮首先从前往后遍历出一个最大值放在最后面,然后从后往前遍历一个最小值放在最前面,即每一轮遍历选出一个最大值和一个最小值。

适合用于大部分元素已经有序的情况

时间复杂度和空间复杂度?是否稳定性?

简单粗暴的鸡尾酒排序:

	public static void jiweijiu1(int[] a) {
		int tem;
		//首先确定外层循环遍历次数
		for (int i = 0; i < a.length/2; i++) {
			//从前往后遍历,选出最大值,外循环每遍历一次,
前面和后面分别多增加一个有序值。故这里	
                        int j = i; j < a.length-1-i;
			for (int j = i; j < a.length-1-i; j++) {
				if (a[j]>a[j+1]) {
					tem = a[j+1];
					a[j+1] = a[j];
					a[j] = tem;
				}
			}
			//从后往前遍历,选出最小值,外循环每遍历一次,
前面和后面分别多增加一个有序值。故这里	
                        int k = a.length-1-i; k > i;
			for (int k = a.length-1-i; k > i; k--) {
				if (a[k-1]>a[k]) {
					tem = a[k];
					a[k] = a[k-1];
					a[k-1] = tem;
				}
			}
		}
	}

第一次优化:进行内层循环的时候,只要存在一次遍历(从前往后遍历或者从后往前遍历)没有交换元素则认为数组有序

	public static void jiweijiu2(int[] a) {
		int tem;
		//当从前往后选最大值或者从后往前遍历选最小值的时候不存再元素的交换,
即可认为次数数组是有序的,
		boolean isSorted;
		//首先确定外层循环遍历次数
		for (int i = 0; i < a.length/2; i++) {
			isSorted = true;
			//从前往后遍历,选出最大值,外循环每遍历一次,
前面和后面分别多增加一个有序值。故这里	
                        int j = i; j < a.length-1-i;
			for (int j = i; j < a.length-1-i; j++) {
				if (a[j]>a[j+1]) {
					tem = a[j+1];
					a[j+1] = a[j];
					a[j] = tem;
					isSorted = false;
				}
			}
			if (isSorted) {
				break;
			}
			isSorted = true;
			//从后往前遍历,选出最小值,外循环每遍历一次,
前面和后面分别多增加一个有序值。故这里	
                        int k = a.length-1-i; k > i;
			for (int k = a.length-1-i; k > i; k--) {
				if (a[k-1]>a[k]) {
					tem = a[k];
					a[k] = a[k-1];
					a[k-1] = tem;
					isSorted = false;
				}
			}
			if (isSorted) {
				break;
			}
		}
	}

第二次优化:进行内层循环遍历的时候,可以找到有序无序的边界下标index,来减少内层循环次数

自己写的,没有考虑到 j 和 k 的初始值,这里还可以在优化一下。

	public static void jiweijiu3(int[] a) {
		int tem;
		boolean isSorted;
		//从前往后遍历的有序无序下标index
		int qianToHouIndex = a.length-1;
		//从后往前遍历的有序无序下标index
		int houToQianIndex = 0;
		//分别用来记录每次交换元素对应的下标index,
在遍历循环中最后一次交换元素的下标index即可认为是有序无序边界
		int changeQthIndex = 0;
		int changeHtqIndex = 0;
		for (int i = 0; i < a.length/2; i++) {
			//前往后
			isSorted = true;
			for (int j = i; j < qianToHouIndex; j++) {
				if (a[j]>a[j+1]) {
					tem = a[j+1];
					a[j+1] = a[j];
					a[j] = tem;
					isSorted = false;
					changeQthIndex = j;
				}
			}
			if (isSorted) {
				break;
			}
			//循环中最后一次交换元素时的下标就是有序无序边界
			qianToHouIndex = changeQthIndex;
			//后往前
			isSorted = true;
			for (int k = a.length-1-i; k > houToQianIndex; k--) {
				if (a[k-1]>a[k]) {
					tem = a[k];
					a[k] = a[k-1];
					a[k-1] = tem;
					isSorted = false;
					changeHtqIndex = k;
				}
			}
			if (isSorted) {
				break;
			}
			houToQianIndex = changeHtqIndex;
		}
	}

考虑 j 和 k 初始值后如下,只修改了内循环中的两个for语句对 j 和 k 初始值赋值

每次外循环既可以确定数组前面部分的有序边界index,也可以确定后面部分的有序边界index,所有可以再次优化。

	public static void jiweijiu3(int[] a) {
		int tem;
		boolean isSorted;
		//从前往后遍历的有序无序下标index
		int qianToHouIndex = a.length-1;
		//从后往前遍历的有序无序下标index
		int houToQianIndex = 0;
		//分别用来记录每次交换元素对应的下标index,
在遍历循环中最后一次交换元素的下标index即可认为是有序无序边界
		int changeQthIndex = 0;
		int changeHtqIndex = 0;
		for (int i = 0; i < a.length/2; i++) {
			//前往后
			isSorted = true;
			for (int j = houToQianIndex; j < qianToHouIndex; j++) {
				if (a[j]>a[j+1]) {
					tem = a[j+1];
					a[j+1] = a[j];
					a[j] = tem;
					isSorted = false;
					changeQthIndex = j;
				}
			}
			if (isSorted) {
				break;
			}
			//循环中最后一次交换元素时的下标就是有序无序边界
			qianToHouIndex = changeQthIndex;
			//后往前
			isSorted = true;
			for (int k = qianToHouIndex; k > houToQianIndex; k--) {
				if (a[k-1]>a[k]) {
					tem = a[k];
					a[k] = a[k-1];
					a[k-1] = tem;
					isSorted = false;
					changeHtqIndex = k;
				}
			}
			if (isSorted) {
				break;
			}
			houToQianIndex = changeHtqIndex;
		}
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值