python版 快速,归并,堆
https://blog.csdn.net/m0_60370702/article/details/123627558?spm=1001.2014.3001.5501
快速排序
时间复杂度:O(nlogn)
最坏情况:O(n²)
public class Main{
public static void main(String[] args) {
int[] arr = {5,8,6,1,4,3,7,2,9};
QuickSort(arr,0,arr.length-1);
for (int i : arr) {
System.out.print(i+", ");
}
}
public static void QuickSort(int[] arr, int left, int right){
if (left < right){
int mid = Partition(arr, left, right);
QuickSort(arr, left, mid-1);
QuickSort(arr, mid+1, right);
}
}
public static int Partition(int[] arr, int left, int right){
int tmp = arr[left];
while (left < right){
while (left < right && arr[right] >= tmp){ // 从右边找比tmp小的数
right--; // 往左走一步
}
arr[left] = arr[right]; // 右边的值写到左边空位上
while (left < right && arr[left] <= tmp){ // 从左边找比tmp大的数
left++; // 往右走一步
}
arr[right] = arr[left]; // 左边的值写到右边空位上
}
arr[left] = tmp; // tmp归位
return left;
}
}
归并排序
时间复杂度:O(nlogn)
空间复制度:O(n)
public class Main{
public static void main(String[] args){
int[] arr = {5,8,6,1,4,3,7,2,9};
MergeSort(arr, 0, arr.length-1);
for (int i : arr) {
System.out.print(i+", ");
}
}
public static void MergeSort(int[] arr, int low, int high){
if (low < high){
int mid = (low + high) / 2;
MergeSort(arr, low, mid);
MergeSort(arr, mid+1, high);
Merge(arr, low, mid, high);
}
}
public static void Merge(int[] arr, int low, int mid, int high){
int left = low, right = mid+1, k = 0;
int[] tmp = new int[high - low + 1];
while (left <= mid && right <= high){ // 只要左右两边都有数
if (arr[left] < arr[right]){
tmp[k++] = arr[left++];
}else{
tmp[k++] = arr[right++];
}
}
// 左边剩下的
while (left <= mid){
tmp[k++] = arr[left++];
}
// 右边剩下的
while (right <= high){
tmp[k++] = arr[right++];
}
System.arraycopy(tmp, 0, arr, low, tmp.length);
}
}
堆排序(大根堆)
时间复杂度:O(nlogn)
public class Main{
public static void main(String[] args) {
int[] arr = {5, 8, 6, 1, 4, 3, 7, 2, 9};
HeapSort(arr);
for (int i : arr) {
System.out.print(i + ", ");
}
}
public static void HeapSort(int[] arr) {
for (int i = (arr.length - 2) / 2; i > -1; i--) {
// i 表示建堆时调整的部分的根的下标
Sift(arr, i, arr.length - 1);
} // for循环完成时,建堆完成
for (int i = arr.length - 1; i > -1; i--) {
// i指向当前堆的最后一个元素
int tmp = arr[0];
arr[0] = arr[i];
arr[i] = tmp;
Sift(arr, 0, i - 1); // i-1是新的high
}
}
public static void Sift(int[] arr, int low, int high) {
// low 堆的根节点, high 堆的最后一个元素的位置
int i = low; // i最开始指向根节点
int j = 2 * i + 1; // j开始是左孩子
int tmp = arr[low]; // 把堆顶存起来
while (j <= high) { // 只要j位置有数
if (j + 1 <= high && arr[j + 1] > arr[j]) { // 如果右孩子大
j++; // j指向右孩子
}
if (arr[j] > tmp) {
arr[i] = arr[j];
i = j; // 往下一层
j = 2 * i + 1;
} else { // tmp更大
// arr[i] = tmp; // 可写可不写
break;
}
}
arr[i] = tmp;
}
}
冒泡排序,选择排序,插入排序
https://blog.csdn.net/m0_60370702/article/details/123360290?spm=1001.2014.3001.5502
希尔排序,计数排序,桶排序,基数排序
https://blog.csdn.net/m0_60370702/article/details/123384238?spm=1001.2014.3001.5502