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

说来惭愧,昨天面试的时候遇到快速排序的笔试题没答上来。搞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
	}
时间: 2024-10-15 02:34:49

java冒泡排序和快速排序的分析的相关文章

Java 冒泡排序与快速排序的实现

冒泡排序   基本特点 (1)基于交换思想的排序算法  (2)从一端开始,逐个比较相邻的两个元素,发现倒序即交换.      (3)一次遍历,一定能将其中最大(小)的元素交换到其最终位置上 排序过程模拟 代码实现 static void Bubble_Sort(int array[]){ for(int i=0;i<array.length;i++) { for(int j=0;j<array.length-i-1;j++) { if(array[j]<array[j+1]) { int

java冒泡排序和快速排序代码

冒泡排序: 基本思想:在要排序的一组数中,对当前还未排好序的范围内的全部数,自上而下对相邻的两个数依次进行比较和调整,让较大的数往下沉,较小的往上冒.即:每当两相邻的数比较后发现它们的排序与排序要求相反时,就将它们互换.public class BubbleSorted{ public BubbleSorted(){ int a[]={49,38,65,97,76,13,27,49,78,34,12,64,5,4,62,99,98,54,56,17,18,23,34,15,35,25,53,51

使用JAVA直观感受快速排序与冒泡排序的性能差异

初学算法,肯定会编写排序算法 其中两个最为有名的就是冒泡排序和快速排序 理论上冒泡排序的时间复杂度为O(N^2),快速排序的时间复杂度为O(NlogN) 下面本门使用JAVA,分别编写三段排序程序 对十万个0-9999的整数进行一次冒泡排序 对十万个0-9999的整数进行1000次快速排序,使用递归完成 对十万个0-9999的整数进行1000次快速排序,使用堆栈完成 对十万个0-9999的整数进行一次冒泡排序: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17

java 交换排序之(冒泡排序、快速排序)

2016年上班第一天,闲来无事,先写篇博文来结束今天.我们大家都知道java的排序算法很多,接下来我就先看看java最常用的几种排序算法的思想源码附上.(本文所有排序只针对值排序,关于对象排序问题待续.....) 1.插入排序(直接插入排序.二分法插入排序.表插入排序.shell排序) 2.选择排序(直接选择排序.堆排序) 3.交换排序(冒泡排序.快速排序) 4.分配排序(基数排序) 5.归并排序(内排序.外排序) 一.java冒泡排序实现(大家最喜欢也是最简单的排序算法,但是性能不是那么ok

交换排序算法---冒泡排序与快速排序

本文介绍两种交换排序方法:冒泡排序.快速排序 冒泡排序 冒泡排序基本思想 每次遍历完序列都把最大(小)的元素放在最前面,然后再对剩下的序列重复前面的一个过程,每次遍历完之后待排序序列就少一个元素,当待排序序列减小为只有一个元素的时候排序就结束了.因此,复杂度在最坏的情况下是O(N ^2). 冒泡排序实现过程 将被排序的记录数组R[1..n]垂直排列,每个记录R[i]看作是重量为R[i].key的气泡.根据轻气泡不能在重气泡之下的原则,从下往上扫描数组R:凡扫描到违反本原则的轻气泡,就使其向上"飘

内部排序算法(一):交换排序(冒泡排序,快速排序)

这是我的博文系列<内部排序算法>的第一篇.所谓排序,就是要整理文件中的记录,使之按关键字递增(或递减)次序排列起来.所谓内部排序,是指在排序过程中,若整个文件都是放在内存中处理,排序时不涉及数据的内.外存交换(外排序的定义则相反). 内部排序法按照策略可以划分为五类:插入排序.选择排序.交换排序.归并排序和分配排序.待排文件的存储方式采用顺序表(或直接用向量)作为存储结构(其他的存储结构还有以链表作为存储结构等). 在这个系列的博文中,我按照排序算法的给出,排序算法的分析(包括算法的时空复杂度

常用排序算法实现[交换排序之冒泡排序、快速排序]

相关知识 1. 稳定排序和非稳定排序: 稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序. 如果排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的列表中R出现在S之前,在排序过的列表中R也将会是在S之前. 2. 内排序和外排序 在排序过程中,所有需要排序的数都在内存,并在内存中调整它们的存储顺序,称为内排序: 在排序过程中,只有部分数被调入内存,并借助内存调整数在外存中的存放顺序排序方法称为外排序. 3.算法分类 排序算法从理论上分为如下几类: (1) 交换排序法:

java.io.BufferedOutputStream 源码分析

BufferedOutputStream  是一个带缓冲区到输出流,通过设置这种输出流,应用程序就可以将各个字节写入底层输出流中,而不必针对每次字节写入调用底层系统. 俩个成员变量,一个是存储数据的内部缓冲区,一个是缓冲区中的有效字节数. /** * The internal buffer where data is stored. */ protected byte buf[]; /** * The number of valid bytes in the buffer. This value

Java split方法源码分析

Java split方法源码分析 1 public String[] split(CharSequence input [, int limit]) { 2 int index = 0; // 指针 3 boolean matchLimited = limit > 0; // 是否限制匹配个数 4 ArrayList<String> matchList = new ArrayList<String>(); // 匹配结果队列 5 Matcher m = matcher(inp