目 录
1、快速排序
1.1、概念+举例
- 找一个数字,作为标准(基准横线)来排序(通常取数组第一个数字!),将数组拆分为2部分,大数在右;小数在左;
- 再将拆分后的数组,继续拆分。
- 递归。【第一次排序,对所有的数据进行排序;之后的排序 对 部分数据 进行排序。】
low、high重合,数组按照基数分配完毕。比基数大的数字,在右边;比基数小的数字,在左边;继续递归。
设定一个基准数a。【通常取第一个数字!】
比a大的数字,往右移动;比a小的数字,往左移动!递归!!!
设置 前后 2个 标记,标记重合,进行下一次 递归!【递归结束条件:开始位置==结束位置】
1.2、完整代码
package demo4;
import java.util.Arrays;
public class QuickSort {
public static void main(String[] args) {
int[] arr = new int[] { 3, 4, 6, 7, 2, 7, 2, 8, 0, 9, 1 };
quickSort(arr, 0, arr.length - 1);
System.out.println(Arrays.toString(arr));
}
// 快速排序
public static void quickSort(int[] arr, int start, int end) {
if (start < end) {
int stard = arr[start]; // 把数组中的第0个数字做为标准数【从数组的开始位置取标准数】
int low = start; // 记录坐标-记录需要排序的下标
int high = end; // 记录坐标
while (low < high) { // 循环找比标准数大的数和比标准数小的数【高右低左】
// 1、右边的数字比标准数大,则数字不需要移动,high--
// stard <= arr[high]:基准数要小于右边指针所指的数字
while (low < high && stard <= arr[high]) {
high--;//基准数小于右边指针所指的数字,high--前移
}
arr[low] = arr[high];// 使用右边的数字替换左边的数
// 2、如果左边的数字比标准数小,则数字不需要移动,low++
while (low < high && arr[low] <= stard) {
low++;//下标右移
}
arr[high] = arr[low];
}
// low、high重合---把标准数赋给低所在的位置的元素
arr[low] = stard;
// low、high重合---根据low与high所在的下标-处理所有的小的数字-从开始位置~低的位置
quickSort(arr, start, low);
// low、high重合---根据low与high所在的下标-处理所有的大的数字-从开始位置~高的位置
quickSort(arr, low + 1, end);
}
}
}
2、插入排序
2.1、概念+举例
认为所有的数字,都是有序的。将数字依次往前移动,一个一个插入到前面的有序序列中!
从第2个数字开始,把之后的数字挨个遍历一遍。遍历的时候,认为前面的数字都是有序的。
在遍历下一个数字的时候,如果该数字比当前数字更小,则将该数字往前移动,直到前面的数字序列有序;
在遍历下一个数字的时候,如果该数字比当前数字更大,则将该数字往后移动,直到已经遍历的数字序列有序。
// 把临时变量(外层for循环的当前元素)赋给不满足条件的后一个元素
arr[j + 1] = temp;
2.2、完整代码
package demo4;
import java.util.Arrays;
public class InsertSort {
public static void main(String[] args) {
int[] arr = new int[] { 5, 3, 2, 8, 5, 9, 1, 0 };
insertSort(arr);
System.out.println(Arrays.toString(arr));
}
// 插入排序
public static void insertSort(int[] arr) {
// 遍历所有的数字【从第2个数字开始比较!依次往后比。】
for (int i = 1; i < arr.length; i++) {
if (arr[i] < arr[i - 1]) { // 如果 当前数字arr[i] 比 前一个数字arr[i - 1] 小
int temp = arr[i]; // 1、把当前遍历数字存起来
int j;
//(内层for循环)遍历当前数字前面所有的数字【temp < arr[j]:当前遍历的数字,要大于temp】
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j + 1] = arr[j]; // 数字后移-把前一个数字赋给后一个数字
}
// 把临时变量(外层for循环的当前元素)赋给不满足条件的后一个元素
arr[j + 1] = temp;
}
}
}
}
3、简单选择排序
3.1、概念+举例
简单选择排序
标注一个相对较小的数字(x),依次向后找,找一个 比 此数字(x) 还小的数字,遍历完此数组,将找到的比x小 且 最小的数字,移至最前面。接着从上一个找到的最小的数字,开始往后找,每次只找数组中最小的元素,将其移至前面。一直这样...
从第1个数字,开始往后找。
从第2个数字,开始往后找。
从第3个数字,开始往后找。
把 所有的数字 遍历一遍,有多少数字,便选多少次最小的数字。
3.2、完整代码
package demo4;
import java.util.Arrays;
public class SelectSort {
public static void main(String[] args) {
int[] arr = new int[] { 3, 4, 5, 7, 1, 2, 0, 3, 6, 8 };
selectSort(arr);
System.out.println(Arrays.toString(arr));
}
// 简单选择排序
public static void selectSort(int[] arr) {
// 遍历所有的数
for (int i = 0; i < arr.length; i++) {
int minIndex = i;
// 把当前遍历的数和后面所有的数依次进行比较,并记录下最小的数的下标
for (int j = i + 1; j < arr.length; j++) {
// 如果后面比较的数比记录的最小的数小。
if (arr[minIndex] > arr[j]) {
// 记录下最小的那个数的下标
minIndex = j;
}
}
// 如果最小的数和当前遍历数的下标不一致,说明下标为minIndex的数比当前遍历的数更小。
if (i != minIndex) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
4、3种排序-综合代码
4.1、完整代码
package sort;
import java.util.Scanner;
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int[] arr = new int[] { 5, 7, 2, 9, 4, 1, 0, 5, 7 };
System.out.println("排序前的数组: " + Arrays.toString(arr));
while (true) {
menu();
int num = sc.nextInt();
switch (num) {
case 0:
System.out.println("程序已结束!");
return;
case 1:
int[] arr1 = arr;
System.out.println("冒泡排序");
bubbleSort(arr1);
System.out.println(Arrays.toString(arr1));
break;
case 2:
int[] arr2 = arr;
System.out.println("快速排序");
quickSort(arr2, 0, arr2.length - 1);
System.out.println(Arrays.toString(arr2));
break;
case 3:
int[] arr3 = arr;
System.out.println("插入排序");
insertSort(arr3);
System.out.println(Arrays.toString(arr3));
break;
case 4:
int[] arr4 = arr;
System.out.println("简单选择排序");
insertSort(arr4);
System.out.println(Arrays.toString(arr4));
break;
}
}
}
private static void menu() {
System.out.println("主菜单");
System.out.println("请选择您需要的排序算法:");
System.out.println("1: 冒泡排序");
System.out.println("2: 快速排序");
System.out.println("3: 插入排序");
System.out.println("4: 简单选择排序");
System.out.println("0: 退出程序!!!");
}
/**
* 1-冒泡排序
*
* @param arr
*/
public static void bubbleSort(int[] arr) {
// 排序过程 比较次数(compare)、移动次数(move)、记录第n趟排序结果
int comnum = 0, movnum = 0, num = 1;
// 控制共比较多少轮
for (int i = 0; i < arr.length - 1; i++) {
// 控制比较的次数
for (int j = 0; j < arr.length - i - 1; j++) { // 减i,比较过的数字,不再进行比较
comnum++;
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
movnum++;
}
}
System.out.println("第" + (num++) + "趟 排序结果: ");
System.out.println(Arrays.toString(arr));
}
System.out.println("排序过程-比较次数:" + comnum + "; 移动次数:" + movnum);
}
/**
* 1-冒泡排序优化
*
* @param arr
*/
public static void bubbleSort2(int[] arr) {
// 控制共比较多少轮
for (int i = 0; i < arr.length - 1; i++) {
boolean flag = false;
// 控制比较的次数
for (int j = 0; j < arr.length - 1 - i; j++) { // 减i,比较过的数字,不再进行比较
if (arr[j] > arr[j + 1]) {
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
flag = true; // 加入标记
}
}
if (flag) { // 如果没有交换过元素,则已经有序!
return;
}
}
}
/**
* 2-快速排序(递归)
*
* @param arr
* @param start
* @param end
*/
public static void quickSort(int[] arr, int start, int end) {
if (start < end) {
int stard = arr[start]; // 把数组中的第0个数字做为标准数【从数组的开始位置取标准数】
int low = start; // 记录坐标-记录需要排序的下标
int high = end; // 记录坐标
while (low < high) { // 循环找比标准数大的数和比标准数小的数【高右低左】
// 右边的数字比标准数大
// stard <= arr[high]:基准数要小于右边指针所指的数字
while (low < high && stard <= arr[high]) {
high--;// 基准数小于右边指针所指的数字,high--前移
}
// 使用右边的数字替换左边的数
arr[low] = arr[high];
// 如果左边的数字比标准数小,则数字不需要移动,low++
while (low < high && arr[low] <= stard) {
low++;// 下标右移
}
arr[high] = arr[low];
}
// low、high重合---把标准数赋给低所在的位置的元素
arr[low] = stard;
// low、high重合---根据low与high所在的下标-处理所有的小的数字-从开始位置~低的位置
quickSort(arr, start, low);
// low、high重合---根据low与high所在的下标-处理所有的大的数字-从开始位置~高的位置
quickSort(arr, low + 1, end);
}
}
/**
* 3-插入排序
*
* @param arr
*/
public static void insertSort(int[] arr) {
// 遍历所有的数字【从第2个数字开始比较!依次往后比。】
for (int i = 1; i < arr.length; i++) {
if (arr[i] < arr[i - 1]) { // 如果 当前数字arr[i] 比 前一个数字arr[i - 1] 小
int temp = arr[i]; // 1、把当前遍历数字存起来
int j;
// (内层for循环)遍历当前数字前面所有的数字【temp < arr[j]:当前遍历的数字,要大于temp】
for (j = i - 1; j >= 0 && temp < arr[j]; j--) {
arr[j + 1] = arr[j]; // 数字后移-把前一个数字赋给后一个数字
}
// 把临时变量(外层for循环的当前元素)赋给不满足条件的后一个元素
arr[j + 1] = temp;
}
}
}
/**
* 4-简单选择排序
*
* @param arr
*/
public static void selectSort(int[] arr) {
// 遍历所有的数
for (int i = 0; i < arr.length; i++) {
int minIndex = i;// 认为当前遍历的数字是最小的
// 把当前遍历的数和后面所有的数依次进行比较,并记录下最小的数的下标
for (int j = i + 1; j < arr.length; j++) { // j = i + 1 从当前数字的第2个开始遍历
// 如果后面比较的数 比 记录的最小的数 更小。
if (arr[minIndex] > arr[j]) {
// 记录 最小的那个数的下标
minIndex = j;
}
}
// 如果最小的数和当前遍历数的下标不一致,说明下标为minIndex的数比当前遍历的数更小。
if (i != minIndex) {
int temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
}
}
}
4.2、运行截图
5、其它排序算法汇总
更多排序:https://blog.csdn.net/weixin_44949135/article/details/106784224
堆排序:https://blog.csdn.net/weixin_44949135/article/details/106832176