排序 —— 算法篇

mac2025-05-24  44

目录

堆排序

归并排序:

冒泡排序 ——> 快速排序:

冒泡排序:



堆排序

/** 构建最小堆 */ public static void MakeMinHeap(int a[], int n) { for (int i = (n - 1) / 2; i >= 0; i--) { MinHeapFixdown(a, i, n); } } // 从i节点开始调整,n为节点总数 从0开始计算 i节点的子节点为 2*i+1, 2*i+2 public static void MinHeapFixdown(int a[], int i, int n) { int j = 2 * i + 1; // 子节点 int temp = 0; while (j < n) { // 在左右子节点中寻找最小的 if (j + 1 < n && a[j + 1] < a[j]) { j++; } if (a[i] <= a[j]) break; // 较大节点下移 temp = a[i]; a[i] = a[j]; a[j] = temp; i = j; j = 2 * i + 1; } } public static void MinHeap_Sort(int a[], int n) { int temp = 0; MakeMinHeap(a, n); for (int i = n - 1; i > 0; i--) { temp = a[0]; a[0] = a[i]; a[i] = temp; MinHeapFixdown(a, 0, i); } }

归并排序:

 * 归并排序的核心是两步:  * 1、把数组分割成左右子树,递归,直到不能在分割为止;  * 2、从最小子树 依次往上 逐层合并

public static void main(String[] args) { int[] arr = {1,2,5,4,6,5,8,7}; int[] temp = new int[8]; print("【原始数组】", arr); merge_sort(arr, 0, arr.length-1, temp); print("【归并排序】", temp); } /** * 递归 将数组分割成左右子树 * @param array * @param first * @param last * @param temp */ public static void merge_sort(int array[], int first, int last, int temp[]) { if (first < last) { int middle = (first + last) / 2; merge_sort(array, first, middle, temp);// 左半部分排好序 merge_sort(array, middle + 1, last, temp);// 右半部分排好序 mergeArray(array, first, middle, last, temp); // 合并左右部分 } } /** * 合并 :将两个序列a[first-middle],a[middle+1-end]合并 * @param array 原始数组 * @param temp 临时存储排序成功的子数组,然后将子数组赋值给原始数组对应的部分 */ public static void mergeArray(int array[], int first, int middle, int last, int temp[]) { int begin = first; //子数组的起始索引 int point = middle; //子数组分割中点 int step = middle + 1; //子数组-右部分的起始点 int end = last; //子数组最后索引 int temp_index = 0; //定义 temp数组的index, 用于为temp数组赋值 while (begin <= point && step <= end) { //如果左子树和右子树都有元素 => 逐个比较添加进temp数组 if (array[begin] <= array[step]) { temp[temp_index] = array[begin]; temp_index++; begin++; } else { temp[temp_index] = array[step]; temp_index++; step++; } } while (begin <= point) { //左子树还没结束,右子树已经结束 temp[temp_index] = array[begin]; temp_index++; begin++; } while (step <= end) { //右子树没结束, 左子树已经结束 temp[temp_index] = array[step]; temp_index++; step++; } for (int ii = 0; ii < temp_index; ii++) { array[first + ii] = temp[ii]; } }

冒泡排序 ——> 快速排序:

快速排序——冒泡(交换)排序的改进——挖坑填空

随机取一个数作为key,将比key大的数放在右边,比key小的数放在左边

分成左右子数组    依次递归

public static void quickSort(int [] arr,int left,int right){ if(left>=right) { return; } int key = arr[left]; //选择第一个数为key int lIndex = left; //记录左移动的下标 int rIndex = right; //记录右移动的下标 while(lIndex < rIndex){ while(lIndex < rIndex && arr[rIndex] > key) { //从右向左 找小于key值 的索引 rIndex--; } if(lIndex < rIndex){ arr[lIndex] = arr[rIndex]; lIndex++; } while(lIndex < rIndex && arr[lIndex] < key) { //从左向右 找大于key值 的索引 lIndex++; } if(lIndex < rIndex){ arr[rIndex] = arr[lIndex]; rIndex--; } } arr[lIndex] = key; quickSort(arr, left, lIndex-1);//递归调用 quickSort(arr, lIndex+1, right);//递归调用 }

冒泡排序:

/** * 冒泡排序 * 思想:两个数比较大小,较大的数下沉(往后),较小的数冒起来(往前)。 */ 方法一: public static int[] BubbleSort(int [] arr){ int temp;//临时变量 boolean flag;//是否交换的标志 for(int i=0; i<arr.length-1; i++){ //表示趟数,一共arr.length-1次。 flag = false; for(int j=arr.length-1; j>i; j--){ if(arr[j] < arr[j-1]){ temp = arr[j]; arr[j] = arr[j-1]; arr[j-1] = temp; flag = true; } } if(!flag) { break; } } return arr; } 方法二: // 复杂度 0.5*n(n+1) // 二次函数, public static int [] sort(int array[]){ int cache; for (int j = 0; j < array.length; j++) { for (int i = 0; i < array.length-j; i++) { if (i+1<array.length-j && array[i]>array[i+1]) { cache = array[i+1]; array[i+1] = array[i]; array[i] = cache; } } print(array); } return array; } public static void main(String[] args) { int [] asd = {5,6,2,14,65,89,21,2,3}; int[] a = BubbleSort(asd); for (int i = 0; i < a.length; i++) { System.out.println(a[i]); } }

 

最新回复(0)