[Algorithm notes] Sorting (fast sorting, merging, heap) java code

Sorting (fast sorting, merging, heap) java code

  1. Fast sorting: the most basic division used for division. In an orderly situation, the efficiency is very low, the optimization plan, and the random selection of division elements
  2. Merge sort: recurse downward first, then merge two ordered arrays
  3. Heap sorting: construct a large top pile, n/ 2-1adjust the structure from bottom to top from the first non-leaf node , and adjust the structure from right to left; swap the top element and the end element + adjust the pile structure (adjust once, adjust 0 node, make it become again Big top pile)

Insert picture description here

import org.junit.Test;
import java.util.Arrays;

public class MySort {
    
    
	@Test
    //快速排序
    public void test1() {
    
    
        int[] a = {
    
    49, 38, 65, 97, 76, 13, 27, 50};
        mergeSort(a, 0, a.length - 1);
        System.out.println("排好序的数组:");
        for (int e : a)
            System.out.print(e + " ");
    }

    private static void quickSort(int[] arr, int start, int end) {
    
    
        // 递归终止条件
        if (start >= end) {
    
    
            return;
        }
        // 第一步,找出分区后枢轴的下标,比如[2,1,3],枢轴为2,分区后枢轴的下标为1
        int pivotIndex = partition(arr, start, end);
        // 第二步,对左子数组排序
        quickSort(arr, start, pivotIndex - 1);
        // 第三步,对右子数组排序
        quickSort(arr, pivotIndex + 1, end);
    }

    private static int partition(int[] arr, int start, int end) {
    
    
        // 确定枢轴元素
        int pivot = arr[start];
        // 定义两个指针(引用),一个指向数组左端,一个指向数组右端
        int left = start;
        int right = end;
        while (left < right) {
    
    
            // 从右往左扫描,寻找比枢轴元素小的,并填入坑中
            while (left < right && arr[right] >= pivot) {
    
    
                right--;
            }
            if (left < right) {
    
    
                arr[left] = arr[right];
                left++;
            }
            // 从左往右扫描,寻找比枢轴元素大的,并填入新坑中
            while (left < right && arr[left] < pivot) {
    
    
                left++;
            }
            if (left < right) {
    
    
                arr[right] = arr[left];
                right--;
            }
        }
        // 扫描完成后,将枢轴元素填入新坑中
        arr[left] = pivot;
        return left;
    }
    
    @Test
    //并归排序
    public void test2() {
    
    
        int[] a = {
    
    49, 38, 65, 97, 76, 13, 27, 50};
        mergeSort(a, 0, a.length - 1);
        System.out.println("排好序的数组:");
        for (int e : a)
            System.out.print(e + " ");
    }

    public void mergeSort(int[] a, int start, int end) {
    
    
        if (start < end) {
    
    //当子序列中只有一个元素时结束递归
            int mid = (start + end) / 2;//划分子序列
            mergeSort(a, start, mid);//对左侧子序列进行递归排序
            mergeSort(a, mid + 1, end);//对右侧子序列进行递归排序
            merge(a, start, mid, end);//合并
        }
    }

    public void merge(int[] a, int left, int mid, int right) {
    
    
        int[] tmp = new int[a.length];//辅助数组
        int p1 = left, p2 = mid + 1, k = left;//p1、p2是检测指针,k是存放指针

        while (p1 <= mid && p2 <= right) {
    
    
            if (a[p1] <= a[p2])
                tmp[k++] = a[p1++];
            else
                tmp[k++] = a[p2++];
        }

        while (p1 <= mid) tmp[k++] = a[p1++];//如果第一个序列未检测完,直接将后面所有元素加到合并的序列中
        while (p2 <= right) tmp[k++] = a[p2++];//同上

        //复制回原素组
        for (int i = left; i <= right; i++)
            a[i] = tmp[i];
    }


    
	@Test
    public void test3() {
    
    
        int[] arr = {
    
    7, 6, 7, 11, 5, 12, 3, 0, 1};
        System.out.println("排序前:" + Arrays.toString(arr));
        heapsort(arr);
        System.out.println("排序前:" + Arrays.toString(arr));
    }

    //堆排序
    public static void heapsort(int[] arr) {
    
    
        //1.构建大顶堆
        for (int i = arr.length / 2 - 1; i >= 0; i--) {
    
    
            //从第一个非叶子结点从下至上,从右至左调整结构
            adjustHeap(arr, i, arr.length);
        }
        //2.调整堆结构+交换堆顶元素与末尾元素
        for (int j = arr.length - 1; j > 0; j--) {
    
    
            swap(arr, 0, j);//将堆顶元素与末尾元素进行交换
            adjustHeap(arr, 0, j);//重新对堆进行调整
        }

    }

    //调整大顶堆
    public static void adjustHeap(int[] arr, int i, int length) {
    
    
        int temp = arr[i];//先取出当前元素i
        for (int k = i * 2 + 1; k < length; k = k * 2 + 1) {
    
    //从i结点的左子结点开始,也就是2i+1处开始
            if (k + 1 < length && arr[k] < arr[k + 1]) {
    
    //如果左子结点小于右子结点,k指向右子结点
                k++;
            }
            if (arr[k] > temp) {
    
    //如果子节点大于父节点,将子节点值赋给父节点(不用进行交换)
                arr[i] = arr[k];
                i = k;
            } else {
    
    
                break;
            }
        }
        arr[i] = temp;//将temp值放到最终的位置
    }

    //交换元素
    public static void swap(int[] arr, int a, int b) {
    
    
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }

}

Guess you like

Origin blog.csdn.net/qq_39457586/article/details/114695797