冒泡排序

时间复杂度O(N^2) ,是不稳定的排序方法!但是可以实现成稳定的!

过程:
 1. 依次比较相邻的两个数,将小数放在前面,大数放在后面。即在第一趟:首先比较第1个和第2个数,将小数放前,大数放后。然后比较第2个数和第3个数,将小数放前,大数放后,如此继续,直至比较最后两个数,将小数放前,大数放后。至此第一趟结束,将最大的数放到了最后。

2. 在第二趟:仍从第一个数开始比较(因为可能由于第2个数和第3个数的交换,使得第1个数不再小于第2个数),将小数放前,大数放后,一直比较到倒数第二个数(倒数第一的位置上已经是最大的),第二趟结束,在倒数第二的位置上得到一个新的最大数(其实在整个数列中是第二大的数)。

3. 如此下去,重复以上过程,直至最终完成排序。

 

public class BubbleSort {
	public int[] bubbleSort(int[] array){
		//自己写的方法
//		for (int i = 0; i < array.length; i++) {
//			for (int j = 1; j < array.length-i; j++) {
//				if(array[j-1]>array[j]){
//					int temp = array[j];
//					array[j]= array[j-1];
//					array[j-1] = temp;
//				}
//			}
//		}
		
		//教程给的方法
		for (int end = array.length-1; end >0; end--) {
			for (int i = 0; i < end; i++) {
				if(array[i]>array[i+1]){
					int temp = array[i+1];
					array[i+1]= array[i];
					array[i] = temp;
				}
			}
		}
		return array;
	}
	
	/**
	 * 对数器的作用:
	 * 		对数器是通过用大量测试数据来验证算法是否正确的一种方式。在算法笔试的时候,我们经常只能确定我们写出的算法在逻辑上是大致
	 * 		正确的,但是谁也不能一次性保证绝对的正确。特别是对于一些复杂的题目,例如贪心算法,我们往往无法在有限时间内用数学公式来
	 * 		推导证明我们程序的正确性。而且在线的OJ一般只会给出有数的几个简单的samples,可能我们的算法在这些简单的samples偶然通过了,
	 * 		但是在一些复杂的samples处却出现了问题。这时我们无法使用复杂的samples来分析调试我们的代码,人工设计样例来测试代码的效率
	 * 		又太低,而且不能确保考虑各种特殊情况。因此,能随机产生不同情况的数据的对数器就派上了用场。
	 * 
	 * 对数器,简而言之,就是一个绝对正确的方法和能产生大量随机样例的随机器的组合。
	 * 
	 * 因为效率的关系,在对数器中,我们要求的绝对正确的算法是没有时间和空间复杂度的限制的,唯一的要求是确保绝对正确。因为只有绝对正确,我们才能通过
	 * 样例的比对,发现我们的代码是在哪里出了错误。
	 * 
	 * 所以在笔试前,应该准备好各种对数器模板,数组、二叉树。。。
	 */
	
	
	//随机数组产生器
	public static int[] generateRandomArray(int size,int value){
		//random()左闭右开,默认产生[0,1)的数字,前面乘上一个整数作为种子,再取整,即生成[0,size]的整数范围,
		//因为达不到size+1,所以取整后最大为size。这里是一个经验,怎么在右开的情况下取到右边的值。
		int[] arr = new int[(int)((size+1)*Math.random())];
		
		for (int i = 0; i < arr.length; i++) {
			arr[i] = (int)((int)((value+1)*Math.random()) - (int)((value)*Math.random()));
		}
		
		return arr;
	}
	
	//绝对正确的方法
	public static void rightMethod(int[] arr){
		Arrays.sort(arr);
	}
	
	//复制数组
	public static int[] copyArray(int[] arr){
		if(arr==null){
			return null;
		}else{
			int[] copy_arr = new int[arr.length];
			for (int i = 0; i < arr.length; i++) {
				copy_arr[i] = arr[i];
			}
			return copy_arr;
		}
	}
	
	//比较两个数组是否内容一致
	public static boolean isEquals(int[] arr1,int[] arr2){
		boolean flag = true;
		//判断两个数组是否内容一致,首先必须都不为空,然后数组长度一致,才需要进行对比
		if(arr1!=null && arr2!=null && arr1.length == arr2.length){
			for(int i = 0; i < arr1.length; i++){
				if(arr1[i] != arr2[i]){
					flag = false;
					break;
				}
			}
		}else{
			flag = false;
		}
		
		return flag;
	}
	
	//打印数组
	public static void print(int[] arr){
		for (int i = 0; i < arr.length; i++) {
			System.out.print(arr[i] + " ");
		}
	}
	
	public static void main(String[] args) {
		int testTime = 1000000;	//测试次数
		boolean success = true;
		for(int i = 0; i < testTime; i++){
			int[] arr = generateRandomArray(10, 100);	//生成随机数组
			int[] arr1 = copyArray(arr);	//复制数组
			int[] arr2 = copyArray(arr);
			BubbleSort bubble = new BubbleSort();
			int[] bubbleResult = bubble.bubbleSort(arr);
			rightMethod(arr1);
			
			//判断两种方法的 结果是否一致
			if(!isEquals(bubbleResult, arr1)){
				success = false;
				print(arr2);
				break;
			}
		}
		
		System.out.println(success ? "Nice!" : "Fucking fucked!");
	}
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值