文章目录
不是吧?o(n^2)的算法你也要讲?
1.冒泡排序
辅助记忆:
i∈[0,N-1) // 循环N-1遍
j∈[0,N-1-i) // 每遍循环要处理的无序部分
swap(j,j+1) // 两两排序(升序/降序)
// c++
void bubble_sort(T arr[], int len) {
int i, j;
for (i = 0; i < len - 1; i++)
for (j = 0; j < len - 1 - i; j++)
if (arr[j] > arr[j + 1])
swap(arr[j], arr[j + 1]);
}
2.选择排序
- 把当前位置记作最小
- 扫描后面所有数,找到最小下标
- 交换最小值与当前值的位置
// c++
void selection_sort(std::vector<T>& arr) {
for (int i = 0; i < arr.size() - 1; i++) {
int min = i;
for (int j = i + 1; j < arr.size(); j++)
if (arr[j] < arr[min])
min = j;
std::swap(arr[i], arr[min]);
}
}
3.插入排序(我最喜欢的n^2算法)
- 你想象一个序列
- 找到最小的,放在第一位
- 找到次小的,放在第二位,以此类推
void insert_sort(std::vector<T>& arr) {
for (int i = 0; i < arr.size(); i++) {
for (int j = i + 1; j < arr.size()-1; j++) {
std::swap(arr[i], arr[j]);
}
}
}
我终于可以讲o(nlogn)的了
// 以下算法均使用 Java 与 c++编写
1.堆排序
// java
package 数据结构与算法;
import java.util.Arrays;
// 堆的性质
// 大顶堆:父节点 > 子节点
// 小顶堆:父节点 < 子节点
// 升序排列大顶堆
// 降序排列小顶堆
// 联想堆排序,快排?
public class 树_堆结构 {
// 测试
public static void main(String[] args) {
int[] arr = {
9, 6, 8, 7, 0, 1, 10, 4, 2 };
int start = (arr.length - 1) / 2;
heapSort(arr);
System.out.println(Arrays.toString(arr));
}
// 堆排序, 这里我默认大顶堆 & 当然你可以通过继承来写
public static void heapSort(int[] arr) {
// 开始位置是最后一个非叶子节点, 即最后一个节点的父节点
int start = (arr.length - 1) / 2;
// 调整为大顶堆
for (int i = start; i >= 0; i--) {
maxHeap(arr, arr.length, i);
}
// 把数组中第0个和堆中最后一个数交换位置, 再把前面的调整为大顶堆
for (int i = arr.length - 1; i > 0; i--) {
// swap
int temp = arr[0];
arr[0] = arr[i];
arr[i] = temp;
maxHeap(arr, i, 0);
}
}
/**
1. 由数组构建大小顶堆(树)
2. 很简单 : 左子节点取 2*index + 1 右子节点取 2*index + 2
*/
// 大顶堆
public static void maxHeap(int[] arr, int size, int index) {
// 左子节点
int leftNode = 2 * index + 1;
// 右子节点
int rightNode = 2 * index + 2;
int max = index;
// 和两个节点对比找出最大的节点
if (leftNode < size && arr[leftNode] > arr[max]) {
max = leftNode;
}
if (rightNode < size && arr[rightNode] > arr[max]) {
max = rightNode;
}
// 交换位置 swap
if (max != index) {
int temp = arr[index];
arr[index] = arr[max];
arr[max] = temp;
// 交换后可能会排好的堆 !注意max
maxHeap(arr, size, max);
}
}
// 小顶堆
public static void minHeap(int[] arr, int size, int index) {
// 左子节点
int leftNode = 2 * index + 1;
// 右子节点
int rightNode = 2 * index + 2;
int min = index;
// 和两个节点对比找出最大的节点
if (leftNode < size && arr[leftNode] < arr[min]) {
min = leftNode;
}
if (rightNode < size && arr[rightNode] < arr[min]) {
min = rightNode;
}
// 交换位置 swap
if (min != index) {
int temp = arr[index];
arr[index] = arr[min];
arr[min] = temp;
// 交换后可能会排好的堆 !注意min
minHeap(arr, size, min);
}
}
// 闲得没事干的重写
public static void minHeap(int p, int[] arr