目录
一、冒泡排序
思路: 每次冒泡操作都会对相邻的两个元素进行比较,每一轮排序就找出未排序序列中最大值放在最后。
优化:第一版优化增加flag标记,没有数字交换直接return,最优时间复杂度O(n) 。第二版优化,增加tempPostion记录内循环最后一次交换的位置,来缩减内循环的次数
public static void bubbleSort(int[] array) {
int len = array.length - 1;
int temp; // 开辟一个临时空间, 存放交换的中间值
int tempPostion = 0; // 记录最后一次交换的位置
// 要遍历的次数
for (int i = 0; i < array.length - 1; i++) {
int flag = 1; // 设置一个标志位
// 依次的比较相邻两个数的大小,遍历一次后,把数组中第i小的数放在第i个位置上
for (int j = 0; j < len; j++) {
// 比较相邻的元素,如果前面的数大于后面的数,交换
if (array[j] > array[j + 1]) {
temp = array[j + 1];
array[j + 1] = array[j];
array[j] = temp;
flag = 0; // 发生交换,标志位置0
tempPostion = j; // 记录交换的位置
}
}
len = tempPostion; // 把最后一次交换的位置给len,来缩减内循环的次数
if (flag == 1) {// 如果没有交换过元素,则已经有序
// System.out.println(Arrays.toString(array));
return;
}
}
// System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int arr[] = {2, 4, 7, 6, 8, 5, 9};
bubbleSort(arr);
System.out.println(Arrays.toString(arr));
}
二、选择排序
思路:对于给定的一组记录,经过第一轮比较后得到最小的记录,然后将该记录的位置与第一个记录的位置交换;重复该过程,直到进行比较的记录只剩下一个为止。
public static void selectSort(int[] array) {
int len = array.length;
for (int i = 0; i < len; i++) {//确定每次开始的位置
int min = array[i];//设定开始数字为最小的值最小值
int flag = i;
for (int j = i + 1; j < len; j++) {//把最小值存放到min,从开始数字向后一个个和min比较,再把最小值存放到min
if (min > array[j]) {
min = array[j];
flag = j;
}
}
if (flag != i) {
array[flag] = array[i];
array[i] = min;
}
}
// System.out.println(Arrays.toString(array));
}
public static void main(String[] args) {
int arr[] = {2, 4, 7, 6, 8, 5, 9};
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
三、直接插入排序
思路:在要排序的一组数中,假设前面(n-1)个数已经是排好顺序的,现在要把第n个数插到前面的有序数中,使得这n个数也是排好顺序的。从最后一个数开始向前循环,如果插入数小于当前数,就将当前数向后移动一位。如此反复循环,直到全部排好顺序。
public static void insertSort(int[] data) {
int temp;
for(int i = 1;i < data.length; i++){// 取第i个数,插入前边的有序的序列
temp = data[i];
int j;
for(j = i - 1; j>=0; j--) {// 从第i-1的位置上开始比较
if(data[j] > temp) {// 若前面的数大,则往后挪一位
data[j+1] = data[j];
} else {
break;// 否则,说明要插入的数比较大
}
}
data[j+1] = temp;// 找到这个位置,插入数据
}
}
public static void main(String[] args) {
int arr[] = {2, 4, 7, 6, 8, 5, 9};
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
四、归并排序
思路:归并排序采用经典的分治(divide-and-conquer)策略。分阶段可以理解为就是递归拆分子序列的过程,递归深度为log2n。治阶段,我们需要将两个已经有序的子序列合并成一个有序序列
扫描二维码关注公众号,回复:
11335088 查看本文章
概括:主要需要两个辅助函数:mergeSort用来递归划分区间,merge用来合并两个数组。
public static void main(String[] args) {
int arr[] = {2, 4, 7, 6, 8, 5, 9};
mergeSort(arr);
System.out.println(Arrays.toString(arr));
}
public static void mergeSort(int[] array) {
int[] temp = new int[array.length];// 在排序前,先建好一个长度等于原数组长度的临时数组,避免递归中频繁开辟空间
mergeSort(array, 0, array.length-1, temp);
// System.out.println(Arrays.toString(array));
}
private static void mergeSort(int[] arr, int left, int right, int []temp) {
if(left < right) {
int mid = (left+right) / 2;
mergeSort(arr, left, mid, temp);// 左边归并排序,使得左子序列有序
mergeSort(arr, mid+1, right, temp);// 右边归并排序,使得右子序列有序
merge(arr, left, mid, right, temp);// 将两个有序子数组合并操作
}
}
private static void merge(int[] arr, int left, int mid, int right, int[] temp) {
int i = left;// 左序列指针
int j = mid+1;// 右序列指针
int t = 0;// 临时数组指针
while (i <= mid && j <= right) {
if(arr[i] <= arr[j]) {
temp[t++] = arr[i++];
} else {
temp[t++] = arr[j++];
}
}
while(i <= mid) {// 将左边剩余元素填充进temp中
temp[t++] = arr[i++];
}
while(j <= right) {// 将右序列剩余元素填充进temp中
temp[t++] = arr[j++];
}
t = 0;
// 将temp中的元素全部拷贝到原数组中
while(left <= right) {
arr[left++] = temp[t++];
}
}
五、快速排序
思路:快速排序使用分治策略来把一个序列(list)分为两个子序列(sub-lists)
(1)选择主元(基准);(2)划分:左指针指向数组第一个元素,右指针指向数组最后一个元素。移动左指针直到比主元大的元素,移动右指针,直到比主元小的元素,交换他们。直到左指针超过右指针。此时主元位于中间位置(3)递归两个小数组。
public static void quickSort(int[] array) {
sort(array, 0, array.length - 1);
// System.out.println(Arrays.toString(array));
}
private static void sort(int[] a, int low, int high) {
int i = low;
int j = high;
if (a.length <= 1) {
return;
}
if (i >= j) {
return;
}
int index = a[i]; // 选择第一个位置元素为主元
while (i < j) {
while (i < j && a[j] >= index)
j--;
if (a[j] < index)
a[i++] = a[j];
while (i < j && a[i] <= index)
i++;
if (a[i] > index)
a[j--] = a[i];
}
a[i] = index; // 将主元放在中心位置
sort(a, low, i - 1);
sort(a, i + 1, high);
}
public static void main(String[] args) {
int arr[] = {2, 4, 7, 6, 8, 5, 9};
quickSort(arr);
System.out.println(Arrays.toString(arr));
}