冒泡排序与快速排序比较

Java冒泡排序

冒泡排序(Bubble Sort)是一种简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。

  冒泡排序算法的运作如下:

  1.  比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2.  对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。在这一点,最后的元素应该会是最大的数。
  3.  针对所有的元素重复以上的步骤,除了最后一个。
  4.  持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。 
  public class Test {
public void maobao(int[] x){
int temp=0;
for(int i=0;i<x.length-1;i++){
for(int j=0;j<x.length-i-1;j++){
                                //从小到大排序 
if(x[j]>x[j+1]){
temp=x[j];
x[j]=x[j+1];
x[j+1]=temp;
}
}
}
for(int i=0;i<x.length;i++){
System.out.print(" "+x[i]+" ");
System.out.println(count);
}
}
public static void main(String[] arg){
Test test=new Test();
int[] x = { 6, 2, 4, 1, 5, 9 };
test.maobao(x);
}
}

例子为从小到大排序,

原始待排序数组| 6 | 2 | 4 | 1 | 5 | 9 |


第一趟排序(外循环)

第一次两两比较6 > 2交换(内循环)

交换前状态| 6 | 2 | 4 | 1 | 5 | 9 |

交换后状态| 2 | 6 | 4 | 1 | 5 | 9 |

 

第二次两两比较,6 > 4交换

交换前状态| 2 | 6 | 4 | 1 | 5 | 9 |

交换后状态| 2 | 4 | 6 | 1 | 5 | 9 |

 

第三次两两比较,6 > 1交换

交换前状态| 2 | 4 | 6 | 1 | 5 | 9 |

交换后状态| 2 | 4 | 1 | 6 | 5 | 9 |

 

第四次两两比较,6 > 5交换

交换前状态| 2 | 4 | 1 | 6 | 5 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

 

第五次两两比较,6 < 9不交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

 

第二趟排序(外循环)

第一次两两比较2 < 4不交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 |

交换后状态| 2 | 4 | 1 | 5 | 6 | 9 |

 

第二次两两比较,4 > 1交换

交换前状态| 2 | 4 | 1 | 5 | 6 | 9 | 
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

 

第三次两两比较,4 < 5不交换

交换前状态| 2 | 1 | 4 | 5 | 6 | 9 | 
交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

 

第四次两两比较,5 < 6不交换

交换前状态| 2 | 1 | 4 | 5 | 6 | 9 |

交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

 

第三趟排序(外循环)

第一次两两比较2 > 1交换

交换后状态| 2 | 1 | 4 | 5 | 6 | 9 |

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

 

第二次两两比较,2 < 4不交换

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 | 
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

 

第三次两两比较,4 < 5不交换

交换后状态| 1 | 2 | 4 | 5 | 6 | 9 | 
交换后状态| 1 | 2 | 4 | 5 | 6 | 9 |

 

第四趟排序(外循环)无交换

第五趟排序(外循环)无交换  

效率分析
      1.        时间复杂度:O(n^2)

冒泡排序耗时的操作有:比较 + 交换(每次交换两次赋值)。时间复杂度如下:

1)        最好情况:序列是升序排列,在这种情况下,需要进行的比较操作为(n-1)次。交换操作为0次。即O(n)

2)        最坏情况:序列是降序排列,那么此时需要进行的比较共有n(n-1)/2次。交换操作数和比较操作数一样。即O(n^2)

3)        渐进时间复杂度(平均时间复杂度):O(n^2)

2.        空间复杂度:O(1)

从实现原理可知,冒泡排序是在原输入数组上进行比较交换的(称“就地排序”),所需开辟的辅助空间跟输入数组规模无关,所以空间复杂度为:O(1)

      3 .    稳定性

       冒泡排序是稳定的,不会改变相同元素的相对顺序。
快速排序

(一)概念及实现

思想:分治策略。

快速排序的原理:通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序。

"保证列表的前半部分都小于后半部分"就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间的比较次数。

 

具体如下(实现为升序)

设数组为a[0n]

1.        数组中找一个元素做为基准(pivot),通常选数组的第一个数。

2.        对数组进行分区操作。使基准元素左边的值都小于pivot,基准元素右边的值都大于等于pivot

3.        pivot值调整到分区后的正确位置。

4.        将基准两边的分区序列,分别进行步骤1~3。(递归)

5.         重复步骤 1~4 ,直到排序完成。
public static void main(String[] arg){
Test test=new Test();
int[] x = { 49, 52, 65,12,45,5 };
test.kuaisu(x, 6);
}
pub   public void kuaisu(int[] a,int num){
if(num>1){//如果长度小于2,则步不用排序
_quick_sort(a, 0, num - 1);
}
for(int ii=0;ii<a.length;ii++){
System.out.print(" "+a[ii]+" ");
}
}
public void _quick_sort(int[] arrays, int start, int end){
if(start>=end){
      return;
}
int i=start;
int j=end;
int value=arrays[i];
boolean flag = true;
while (i != j) {
if (flag) {
if (value > arrays[j]) {
   int temp = arrays[i];
   arrays[i] = arrays[j];
   arrays[j] = temp;
   flag=false;
}else{
j--;
}
}else{
if(value<arrays[i]){
  int temp = arrays[i];
  arrays[i] = arrays[j];
  arrays[j] = temp;
  flag=true;
}else{
i++;
}
}
}
for (int k = 0; k < arrays.length; k++) {
System.out.print(arrays[k] + " ");
   }
System.out.println();
_quick_sort(arrays, start, j-1);
_quick_sort(arrays, i+1, end);
}  

(二)算法复杂度

1.        时间复杂度:O(nlog2n)

快速排序耗时的操作有:比较 + 交换(每次交换两次赋值)。时间复杂度如下:

1)        最好情况:选择的基准值刚好是中间值,分区后两分区包含元素个数接近相等。因为,总共经过x次分区,根据2^x<=n得出x=log2n,每次分区需用n-1个元素与基准比较。所以O(nlog2n)

2)        最坏情况:每次分区后,只有一个分区包含除基准元素之外的元素。这样就和冒泡排序一样慢,需n(n-1)/2次比较。即O(n^2)

3)        渐进时间复杂度(平均时间复杂度):O(nlog2n)

2.        空间复杂度:O(1)

从实现原理可知,快速排序是在原输入数组上进行比较分区的(称“就地排序”),所需开辟的辅助空间跟输入数组规模无关,所以空间复杂度为:O(1)

 

(三)稳定性

快速是不稳定的,会改变相同元素的相对顺序。如示例,以第一个基准 89排序时,首先将最后一个元素-7移到了第一个分区的第一个位置上。改变了与第二个-7的相对顺序。    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值