时间复杂度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!");
}
}