插入排序
- 将0索引的元素到N索引的元素看做是有序的,把N+1索引的元素到最后一个当成是无序的。
- 遍历无序的数据,将遍历到的元素插入有序序列中适当位置,如遇到相同数据,插在后面
- N的范围:0~最大索引
public class A03_InsertDemo {
public static void main(String[] args) {
int[] arr1 = {3, 44, 38, 5, 47, 15, 36, 26, 27, 2, 46, 4, 19, 50, 48};
int[] arr = {1, 2, 4,3};
//1。找到无序的那一组数组是从哪个索引开始的
int startIndex = -1;
for (int i = 0; i < arr.length - 1; i++) {
if (arr[i] > arr[i + 1]) {
startIndex = i + 1;
break;
}
}
// if (startIndex == -1) {
// System.out.println("原数组有序");
// }
//2。遍历从startIndex开始到最后一个元素,依次得到无序的那一组数据中的每一个元素
for (int i = startIndex; i < arr.length; i++) {
//记录当前要插入数据的索引
int j = i;
while (j > 0 && arr[j] < arr[j - 1]) {
//交换位置
int temp = arr[j];
arr[j] = arr[j - 1];
arr[j - 1] = temp;
j--;
}
}
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
}
递归算法
- 递归指方法中调用方法本身的现象。
- 递归的注意点
-
- 递归一定要有出口,否则就会出现内存溢出
- 递归的作用:
-
- 把一个复杂的问题层层转化为一个与原问题相似的规模较小的问题来解决
-
- 递归策略只需少量的程序就可描述出解题过程所需要的多次重复计算
- 书写递归的两个核心
-
- 找出口:什么时候不再调用方法
-
- 找规则:如何把大问题变成规模较小的问题
练习1:1~100求和
public class A04_RecursionDemo2 {
public static void main(String[] args) {
System.out.println(getSum(100));
}
public static int getSum(int number) {
if (number == 1) {
return 1;
}
return number + getSum(number - 1);
}
}
练习2:递归求阶乘
需求:用递归求5的阶乘,并把结果在控制台输出
public class A04_RecursionDemo1 {
public static void main(String[] args) {
System.out.println(getFactorRecursion(5));
}
public static int getFactorRecursion(int number) {
if (number == 1) {
return 1;
}
return number * getFactorRecursion(number - 1);
}
}
快速排序
- 第一轮:把0索引的数字作为基准数,确定基准数在数组中正确的位置
- 比基准数小的全部在左边,比基准数大的全部在右边。
基准数归位
public class A05_QuickSortDemo {
public static void main(String[] args) {
int[] arr = {6, 1, 2, 7, 9, 3, 4, 5, 10, 8};
quickSort(arr, 0, arr.length - 1);
for (int i = 0; i < arr.length; i++) {
System.out.print(arr[i] + " ");
}
}
public static void quickSort(int[] arr, int i, int j) {
int start = i;
int end = j;
//递归出口
if (start > end) {
return;
}
int baseNumber = arr[i];
while (start != end) {
//利用end,从后往前开始找,找比基准数小的数字
while (true) {
if (end <= start || arr[end] < baseNumber) {
break;
}
end--;
}
//利用start,从前往后开始找,找比基准数大的数字
while (true) {
if (end <= start || arr[start] > baseNumber) {
break;
}
start++;
}
//把end和start指向的元素进行交换
int temp = arr[start];
arr[start] = arr[end];
arr[end] = temp;
}
//基准数归位
int temp = arr[i];
arr[i] = arr[start];
arr[start] = temp;
//基准数两边重复
quickSort(arr, i, start - 1);
quickSort(arr, start + 1, j);
}
}
总结
- 冒泡排序:
-
- 相邻的元素两两比较,小的放前面,大的放后面
- 选择排序:
-
- 从0索引开始,拿着每一个索引上的元素跟后面的元素依次比较。
-
- 小的放前面,大的放后面,以此类推
- 插入排序
-
- 将数组分为有序和无序两组,遍历无序数组,将元素插入到有序序列中即可。
- 快速排序
-
- 将排序范围中的第一个数字作为基准数,再定义两个变量start,end
-
- start从前往后找比基准数大的,end从后往前找比基准数小的
-
- 找到之后交换start和end指向的元素,并循环这一过程,直到start和end处于同一位置,该位置就是基准数在数组中应存入的位置,再让基准数归位。
-
- 归位后的效果:基准数左边的,比基准数小,基准数右边的,比基准数大