十大经典排序算法
冒泡排序(Bubble Sort)就像水里的气泡一样,一直往上浮,所以我们称它为冒泡排序。他的原理是依次比较相邻的两个元素,如果前面的比后面的大就交换这两个数字的值,这样一轮比较完之后,数组中最后一个元素就是最大的了,如下图所示。
这样只需要经过 n-1 轮比较即可完成排序。实现过程如下。
- 首先比较相邻的两个元素,如果当前元素比下一个大,就交换他俩的值。然后继续下一对相邻元素的比较,一直比较下去,直到没有元素可比较为止,这一轮结束之后基本上就把最大的元素放到最后了。
- 除了最后一个元素不参与比较之外,继续上一步的操作,这一轮比较之后就会把第二大的元素放到数组的倒数第二个位置。
- 重复上面的步骤,我们会发现每次比较的元素越来越少,直到最后没有元素可比较为止。
// 冒泡排序。
public void sort(int[] nums) {
int length = nums.length;
for (int i = 1; i < length; i++) {// 只需要比较 n-1 轮即可。
for (int j = 0; j < length - i; j++) {
// 如果当前元素大于它的下一个元素,则交换他俩的值。
if (nums[j] > nums[j + 1]) {
swap(nums, j, j + 1);
}
}
}
}
// 交换数组中两个元素的值。
private void swap(int[] nums, int i, int j) {
int tmp = nums[i];
nums[i] = nums[j];
nums[j] = tmp;
}
冒泡排序的优化
如果一个数组是有序的或者在排序几轮之后剩下的都是有序的,基本上就不需要在排了,比如数组 [6,1,2,3,4,5] ,当第一轮把 6 放到后面之后,就变成了 [1,2,3,4,5,6] ,剩下的就不需要在排了,直接终止即可。
public void sort(int[] nums) {
int length = nums.length;
for (int i = 1; i < length; i++) {
boolean ordered = true;// 标记,判断剩下的元素是否是有序的。
for (int j = 0; j < length - i; j++) {
if (nums[j] > nums[j + 1]) {
swap(nums, j, j + 1);
ordered = false;// 如果发生了交换说明不是有序的。
}
}
if (ordered)// 如果没有发生交换,说明剩下的是有序的,剩下的不需要再排了。
break;
}
}
稳定性分析
冒泡排序是相邻两个元素的比较,只有当前元素比下一个大才会交换,所以即使是相等的,他们的相对顺序也始终保持不变,所以他是稳定的。
时间复杂度:O(n^2)
稳定性:稳定
冒泡排序 ,选择排序 ,插入排序 ,快速排序 ,归并排序 ,堆排序 ,桶排序 ,基数排序 ,希尔排序 ,计数排序 ,位图排序 ,拓扑排序 ,二叉树排序 ,Bogo排序 ,睡眠排序 ,鸡尾酒排序 ,侏儒排序 ,臭皮匠排序 ,图书馆排序 ,珠排序 ,链表排序 ,鸽巢排序 ,奇偶排序 ,慢速排序 ,耐心排序 ,梳排序 ,煎饼排序 ,插值排序 |