java冒泡排序和快速排序的分析

3 篇文章 0 订阅

      说来惭愧,昨天面试的时候遇到快速排序的笔试题没答上来。搞java的长期接触的是业务方面的东西,特别是web方向的java,久而久之在学校里面学的最基本的一些东西给忘记了。网上搜索了这两种算法,基本都是当年书本的解释,个人不是很喜欢。现将自身强化后的解释描述出来,加强记忆,最近有面试的同志不妨看看。

 

1.冒泡排序

书本上的基本理念是左边元素跟右侧元素一个个对比,有更小的就交换。

我将此分解为:

a.将数组的最小元素放在左边;

b.对右边做递归;

这个比较简单,实现a的代码:

	// a.将数组的最小元素放在左边
	public static void bubbleBasic(int[] list) {
		// 基本前提
		if(list != null && list.length > 1) {
			
			// 从第二个元素开始对比
			for(int i=1;i<list.length;i++) {
				
				// 发现更小的就替换
				if(list[0] > list[i]) {
					int tmp = list[0];
					list[0] = list[i];
					list[i] = tmp;
				}
			}
		}
	}

a+b的代码:

	// a+b.完整的冒泡排序
	public static void bubbleSort(int[]list, int begin) {
		if(list != null && (list.length - begin) > 1) {
			for(int i=begin+1;i<list.length;i++) {
				if(list[begin] > list[i]) {
					int tmp = list[begin];
					list[begin] = list[i];
					list[i] = tmp;
				}
			}
			bubbleSort(list, begin +1);
		}
	}

当然有更简单的不用递归的方式的书本代码:

	// 书本的冒泡排序
	public static void bubbleBook(int[] list) {
		if(list != null && list.length > 1) {
			for(int i = 0 ; i < list.length-1 ; i++){
				for(int j = i+1 ; j < list.length ; j++){
					if(list[i] > list[j]) {
						int tmp = list[i];
						list[i] = list[j];
						list[j] = tmp;
					}
				}
			}
		}
	}


2.快速排序

书本上的基本理念是高位低位交叉对比,把数组分成两部分,左边都小于某个元素A,右边都大于A。

个人感觉这个描述很晕,其实是包含两部分,1.交叉对比,2.左边都小右边都大。我屏蔽掉第1点,把A固定成第一个元素,将此问题分解为:

a.把数组第一个元素放在某个位置,使得左边都小于它,右边都大于它;

b.对左右做递归;

对于a,不限制实现方式,相信绝大部分人都能做到。其实嘛算法就是要理解思想,实现方式是很多的,当然我这里也是用交叉对比来实现,我比较喜欢叫左右压缩对比。

实现a的代码:

	// a.把数组第一个元素放在某个位置,使得左边都小于它,右边都大于它
	public static void quickBasic(int[] list) {
		
		// 基本前提
		if(list != null && list.length > 1) {
			
			// 第一个元素当前位置
			int i_current = 0;
			
			// 得到左右边界
			int i_left = 0;
			int i_right = list.length -1;
			
			// 只要右边界还大于左边界,说明还有压缩空间
			while(i_left < i_right) {
				
				// 不断压缩右边界,直到没有压缩空间或者出现比第一个元素更小的元素
				while(i_current < i_right && list[i_current] < list[i_right]) {
					i_right--;
				}
				// 交换元素(即使没找到更小元素也交换,因为一直找不到的话i_right最终会等于i_current,这时候就是自身跟自身交换,就当冗余步骤好了)
				int tmp = list[i_current];
				list[i_current] = list[i_right];
				list[i_right] = tmp;
				// 第一个元素的位置已经改变
				i_current = i_right;
				
				
				//----------元素交换到右边后开始对左边压缩,跟上面的过程完全相反----------
				while(i_current > i_left && list[i_current] > list[i_left]) {
					i_left++;
				}
				tmp = list[i_current];
				list[i_current] = list[i_left];
				list[i_left] = tmp;
				i_current = i_left;
				
				//-----------返回while重复上面过程----------
			}
			
			//-----------程序运行到这里,已经没有压缩空间了,功能完成,这时候i_left = i_current = i_right
		}
	}

a+b的代码:

	// a+b.完整的快速排序
	public static void quickSort(int[] arr, int leftIndex, int rightIndex){
		if(arr != null && leftIndex < rightIndex) {
			
			// 备份一下初始化的左右边界,递归时候用到
			int _leftIndex = leftIndex;
			int _rightIndex = rightIndex;
			
			int currentIndex = leftIndex;
			while(leftIndex < rightIndex) {
				while(currentIndex < rightIndex && arr[currentIndex] < arr[rightIndex]) {
					rightIndex--;
				}
				int tmp = arr[currentIndex];
				arr[currentIndex] = arr[rightIndex];
				arr[rightIndex] = tmp;
				currentIndex = rightIndex;
				
				while(leftIndex < currentIndex && arr[leftIndex] < arr[currentIndex]) {
					leftIndex++;
				}
				tmp = arr[currentIndex];
				arr[currentIndex] = arr[leftIndex];
				arr[leftIndex] = tmp;
				currentIndex = leftIndex;
			}
			
			// 左右开始递归
			quickSort(arr, _leftIndex, currentIndex-1);
			quickSort(arr, currentIndex+1, _rightIndex);
		}
	}

快速排序暂时没发现不用递归能实现的方法。


上述方法的测试实例:

	public static void main(String[] args) {
		int[] list = new int[]{2,1,4,5,8,7,6,3,9,0};
		bubbleBasic(list);
		// 结果是0,2,4,5,8,7,6,3,9,1(打印方法就不写了)
		
		list = new int[]{2,1,4,5,8,7,6,3,9,0};
		bubbleSort(list, 0);
		// 结果是0,1,2,3,4,5,6,7,8,9
		
		list = new int[]{2,1,4,5,8,7,6,3,9,0};
		bubbleBook(list);
		// 结果是0,1,2,3,4,5,6,7,8,9
		
		list = new int[]{2,1,4,5,8,7,6,3,9,0};
		quickBasic(list);
		// 结果是0,1,2,5,8,7,6,3,9,4
		
		list = new int[]{2,1,4,5,8,7,6,3,9,0};
		quickSort(list, 0, list.length -1);
		// 结果是0,1,2,3,4,5,6,7,8,9
	}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值