冒泡排序(BubbleSort):循环遍历要排序的元素,依次比较相邻的两个元素,如果他们的顺序错误就把他们交换位置。每一次循环遍历,直到数组的末尾。因为越大的元素会经过交换到数组的前端(升序或降序排列),整个过程就像气泡最终会上浮到顶端一样,称之为“冒泡排序”。
原理步骤:
1、比较相邻的两个元素。如果第一个比第二个大就交换他们的位置。
2、对每一个相邻元素做同样的工作,直到数组的末尾,得到这组元素最大的数,交换到数组的末尾。
3、针对所有元素重复2同样的步骤,除了上次循环末尾以后的元素。
4、持续遍历比较两个相邻元素,比较次数越来越小。直到没有数字可以比较。
public int[] bubbleSort( ) {
//数组填充元素对象
int[] arr = {12,23,34,56,56,56,78};
for(int i = 0; i < arr.length-1; i++) {
boolean flag = false; //判断交换标签,数组有序
// j < arr.length-1减去i是排序已排序的元素
for(int j = 0; j < arr.length-i-1; j++) {
//-1为了防止溢出,省略比较已排序的元素
if(arr[j] > arr[j+1]) {
int temp = arr[j];
arr[j]=arr[j+1];
arr[j+1]=temp;
flag = true;
}
}
if(!flag){
break;
}
}
return arr;
}
时间的复杂度:
1、如果是一个有序的数组包含N个元素,第一次外层循环后就返回,只发生内部N-1比较。这是最好的情况,此时的时间复杂度是O(N)。
2、如果是一个逆序列的数组包含N个元素,此时的时间复杂度O(N²)。
双向冒泡排序(CocktailShakerSort):冒泡排序的一种变形,也是一种稳定的排序。区别:普通的冒泡排序仅是一种方向从低到高比较序列里的每个元素,从前向后按一个次序遍历;双向冒泡排序,包括两个方向,先从前向后,再从后向前,从前向后遍历后能激励最后发生交换的两个元素位子,从后向前遍历时就从这个位子开始。让小的浮出水面,还可以使大的沉到水底。
不同的是,普通的冒泡排序算法仅是从低到高比较序列里的每个元素,或者说普通的冒泡排序算法只能每次从前向后按一个次序进行遍历,而Shaker排序方法每次遍历却包括两个方向,先从前向后再从后向前,在从前往后遍历后能记录最后发生交换的两个元素位置,从后往前遍历时就从这个位置开始。这种双向交替比较不仅可以使小的浮上水面,同时也会使大的沉倒水底,因而较普通的冒泡算法在效率上有所改进。
public T[] CocktailShakerSort(T[] array) {
int length = array.length;
int left = 0;//左边起始位置
int right = length - 1;//右边起始位置
int swappedLeft, swappedRight;
while (left < right) {
swappedRight = 0;
for (int i = left; i < right; i++) {
if (SortUtils.less(array[i + 1], array[i])) {
SortUtils.swap(array, i, i + 1);
swappedRight = i;
}
}
right = swappedRight;
swappedLeft = length - 1;
for (int j = right; j > left; j--) {
if (SortUtils.less(array[j], array[j - 1])) {
SortUtils.swap(array, j - 1, j);
swappedLeft = j;
}
}
left = swappedLeft;
}
return array;
}