排序分类
1、内部排序
指将需要处理的所有数据都加载到内部存储器中进行排序。
2、外部排序
数据量过大,无法全部加载到内存中,需要借助外部存储进行排序。
一、冒泡排序
冒泡排序也属于内部排序法,属于交换排序
。
基本思想
通过对待排序序列从前向后(从下标较小的元素开始),依次比较相邻元素的值,若发现逆序则交换,使值较大的元素逐渐从前移向后部,就像水底下的气泡一样逐渐向上冒。
因为排序的过程中,各元素不断接近自己的位置,如果一趟比较下来没有进行过交换,就说明序列有序,因此要在排序过程中设置一个标志flag判断元素是否进行过交换。从而减少不必要的比较。
图解
int[] nums = new int[]{
79,56,90,4,32,27,8};
①第一轮,把最大的数沉到最下面。
79与56相比,大于56,交换
79与90相比,相等,不变
90与4相比,大于4,交换
90与32相比,大于32,交换
90与27相比,大于27,交换
90与8相比,大于8,交换
②第二轮,把第二大的数沉到倒数第二。
56与79相比,小于,不变
79与4相比,大于,交换
79与32相比,大于,交换
79与27相比,大于,交换
90与8相比,大于,交换
③第n轮,以此类推…
代码实现
public class BubbleSortDemo {
public static void main(String[] args) {
int[] nums = new int[]{
79,56,90,4,32,27,16,88,35,32};
System.out.println("排序前:");
for (int num : nums) {
System.out.print(num + " ");
}
bubbleSort(nums);
System.out.println("\n排序后:");
for (int num : nums) {
System.out.print(num + " ");
}
}
/**
* 冒泡排序算法
* @param nums 要排序的数组
*/
public static void bubbleSort(int[] nums){
boolean isSort = false; // 在一次流程中是否排过序
int temp = 0; // 临时变量
for (int i = 0; i < nums.length; i++){
for (int j = 0; j < nums.length - 1 - i; j++){
if (nums[j] > nums[j + 1]){
// 如果前面的数大于后面的数,交换
temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
// 因为排序发生过变动,所以需要继续排序
isSort = true;
}
}
if (isSort){
// 发生了变动,重置,继续排序
isSort = false;
}else{
// 没有发生变动,说明已经排好序了
break;
}
}
}
}
二、快速排序
快速排序(Quicksort)是对冒泡排序的一种改进,属于交换排序
。
基本思想
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。
图解
int[] nums = new int[]{
11,21,28,12,5,8,30};
①第一轮
②第二轮、第三轮
③分成两组之后,递归开始
代码实现
public class quickSortDemo {
public static void main(String[] args) {
int a = (int) Math.ceil(9 / 2);
System.out.println(a);
int[] nums = new int[]{
79,56,90,4,32,27,16,88,35,32};
System.out.println("排序前:");
for (int num : nums) {
System.out.print(num + " ");
}
quickSort(nums,0,nums.length - 1);
System.out.println("\n排序后:");
for (int num : nums) {
System.out.print(num + " ");
}
}
/**
* 快速排序算法
* @param nums 要排序的数组
* @param left 数组最左端记录的下标
* @param right 数组最右端记录的下标
*/
public static void quickSort(int[] nums, int left, int right){
if (left > right){
// 不合理
return;
}
// 定义两个变量(哨兵)来接管left和right,left和right后面会用得到
int l = left;
int r = right;
// 定义一个参考值,这里以最右端的作为参考值
int reference = nums[l];
// 定义一个临时变量,用于交换使用
int temp = 0;
while (l != r){
// 只要两个哨兵没有碰头就继续找
// 参考值取的是左边的,则让右边的先找比参考值小的数
while(nums[r] >= reference && l < r){
// 没找到,继续往前找
r--;
}
// 右边已经找到了,让左边的去找比参考值大的数
while(nums[l] <= referen