十大排序

十大排序

排序总结图

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

/**
 * @author Ogleede
 * @Description
 * @create 2022-07-31-16:28
 */
public class sort {
    static class ListNode {
        int val;
        ListNode next;

        ListNode(int x) {
            val = x;
        }
    }

    private static Random rd = new Random(20220731);

    public static void swap(int[] arr, int x, int y) {
        int tmp = arr[x];
        arr[x] = arr[y];
        arr[y] = tmp;
    }
	
    
    /**
    * 冒泡排序
    */
    public static void bubbleSort(int[] arr) {
        if (arr == null || arr.length < 2) return;

        int n = arr.length;
        for (int i = 0; i < n - 1; ++i) {
            for (int j = i + 1; j < n; ++j) {
                if (arr[j] < arr[i]) {
                    swap(arr, i, j);
                }
            }
        }
    }
	
    
    /**
    * 快速排序
    */
    public static int partition(int[] arr, int l, int r) {
        int idx = l + rd.nextInt(r - l);
        swap(arr, l, idx);
        int pivot = arr[l], pivotIdx = l;
        for (int i = l + 1; i <= r; ++i) {
            if (arr[i] < pivot) {
                swap(arr, i, ++pivotIdx);
            }
        }
        swap(arr, l, pivotIdx);
        return pivotIdx;
    }
	
    public static void quickSort(int[] arr, int l, int r) {
        if (l >= r) return;
        int idx = partition(arr, l, r);
        int tl = idx - 1, tr = idx + 1;
        while (tl >= l && arr[tl + 1] == arr[tl]) --tl;
        while (tr <= r && arr[tr - 1] == arr[tr]) ++tr;
        quickSort(arr, l, tl);
        quickSort(arr, tr, r);
    }
	
    
    /**
    * 插入排序
    */
    public static void insertSort(int[] arr) {
        int n = arr.length;
        int preIdx = 0, cur = 0;
        for (int i = 1; i < n; ++i) {
            preIdx = i - 1;
            cur = arr[i];
            while (preIdx >= 0 && arr[preIdx] > cur) {
                arr[preIdx + 1] = arr[preIdx];
                --preIdx;
            }
            arr[preIdx + 1] = cur;
        }
    }
	
    
    /**
    * 希尔排序
    */
    public static void shellSort(int[] nums) {
        int n = nums.length;
        for (int gap = n / 2; gap > 0; gap >>= 1) {
            for (int i = gap; i < n; ++i) {
                int j = i, cur = nums[i];
                while (j - gap >= 0 && cur < nums[j - gap]) {
                    nums[j] = nums[j - gap];
                    j -= gap;
                }
                nums[j] = cur;
            }
        }
    }
	
    
    /**
    * 选择排序
    */
    public static void selectSort(int[] nums) {
        int n = nums.length;
        int min = 0, minIdx = 0;
        for (int i = 0; i < n; ++i) {
            min = Integer.MAX_VALUE;
            for (int j = i; j < n; ++j) {
                if (nums[j] < min) {
                    min = nums[j];
                    minIdx = j;
                }
            }
            swap(nums, i, minIdx);
        }
    }
	
    
    /**
    * 堆排序
    */
    public static void heapify(int[] nums, int n, int i) {
        if (i >= n) return;
        int c1 = 2 * i, c2 = 2 * i + 1;
        int max = i;
        if (c1 < n && nums[c1] > nums[max]) max = c1;
        if (c2 < n && nums[c2] > nums[max]) max = c2;
        if (max != i) {
            swap(nums, i, max);
            heapify(nums, n, max);
        }
    }

    public static void buildHeap(int[] nums, int n) {
        int lastNode = n - 1;
        int parentNode = lastNode / 2;
        for (int i = parentNode; i >= 0; --i) {
            heapify(nums, n, i);
        }
    }

    public static void heapSort(int[] nums) {
        int n = nums.length;
        buildHeap(nums, n);
        for (int i = n - 1; i > 0; --i) {
            swap(nums, i, 0);
            heapify(nums, i, 0);
        }
    }
	
    
    /**
    * 归并两个排序列表,递归
    */
    public static ListNode mergeTwoLists1(ListNode l1, ListNode l2) {
        if (l1 == null) {
            return l2;
        } else if (l2 == null) {
            return l1;
        } else if (l1.val < l2.val) {
            l1.next = mergeTwoLists1(l1.next, l2);
            return l1;
        } else {
            l2.next = mergeTwoLists1(l1, l2.next);
            return l2;
        }
    }	
	
    
    /**
    * 归并两个排序链表,迭代
    */
    public static ListNode mergeTwoLists2(ListNode l1, ListNode l2) {
        if (l1 == null && l2 == null) return null;
        if (l2 == null) return l1;
        else if (l1 == null) return l2;
        ListNode dh = new ListNode(0), p = dh;
        if (l1.val < l2.val) {
            p.next = l1;
            l1 = l1.next;
        } else {
            p.next = l2;
            l2 = l2.next;
        }
        p = p.next;

        while (l1 != null && l2 != null) {
            if (l1.val < l2.val) {
                p.next = l1;
                l1 = l1.next;
            } else {
                p.next = l2;
                l2 = l2.next;
            }
            p = p.next;
        }
        if (l1 != null) p.next = l1;
        if (l2 != null) p.next = l2;
        return dh.next;
    }
	
    
    /**
    * 归并多个排序链表
    */
    public static ListNode mergeKLists(ListNode[] lists) {
        if (lists == null || lists.length == 0) return null;
        int k = lists.length, idx = k;
        while (idx > 1) {
            idx = 0;
            for (int i = 0; i < k; i += 2) {
                if (i == k - 1) {
                    lists[idx++] = lists[i];
                } else {
                    lists[idx++] = mergeTwoLists1(lists[i], lists[i + 1]);
                }
            }
            k = idx;
        }
        return lists[0];
    }
	
    
    /**
    * 归并排序,非静态,一个tmp数组
    */
    private int[] tmp;

    public void mergeSort(int[] nums, int l, int r) {
        if (l >= r) return;

        int mid = (l + r) >> 1;
        mergeSort(nums, l, mid);
        mergeSort(nums, mid + 1, r);

        int m = l, n = mid + 1;
        for (int i = l; i <= r; ++i) {
            if (m == mid + 1) {
                tmp[i] = nums[n++];
            } else if (n == r + 1) {
                tmp[i] = nums[m++];
            } else if (nums[m] < nums[n]) {
                tmp[i] = nums[m++];
            } else {
                tmp[i] = nums[n++];
            }
        }

        for (int i = l; i <= r; ++i) {
            nums[i] = tmp[i];
        }
    }
	
    
    /**
    * 归并排序,静态创建多个小tmp数组
    */
    public static void mergeSort2(int[] nums, int l, int r) {
        if (l >= r) return;

        int mid = (l + r) >> 1;
        mergeSort2(nums, l, mid);
        mergeSort2(nums, mid + 1, r);

        int m = l, n = mid + 1;
        int[] tmp = new int[r - l + 1];
        for (int i = l; i <= r; ++i) {
            if (m == mid + 1) {
                tmp[i - l] = nums[n++];
            } else if (n == r + 1) {
                tmp[i - l] = nums[m++];
            } else if (nums[m] < nums[n]) {
                tmp[i - l] = nums[m++];
            } else {
                tmp[i - l] = nums[n++];
            }
        }

        for (int i = l; i <= r; ++i) {
            nums[i] = tmp[i - l];
        }
    }
	
    
    /**
    * 计数排序
    */
    public static void countSort(int[] nums) {
        if (nums == null || nums.length < 2) return;
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        for (int num : nums) {
            min = Math.min(min, num);
            max = Math.max(max, num);
        }

        int[] counts = new int[max - min + 1];
        for (int num : nums) {
            ++counts[num - min];
        }
        int idx = 0;
        for (int j = 0; j < counts.length; ++j) {
            for (int i = counts[j]; i > 0; --i) {
                nums[idx++] = j + min;
            }
        }
    }
	
    
    /**
    * 桶排序
    */
    public static void bucketSort(int[] nums, int bucketSize) {
        if (nums == null || nums.length < 2) return;
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
        for (int num : nums) {
            min = Math.min(min, num);
            max = Math.max(max, num);
        }

        int bucketCnt = (max - min) / bucketSize + 1;
        List<Integer>[] buckets = new List[bucketCnt];
        int[] res = new int[nums.length];

        for (int i = 0; i < buckets.length; ++i) {
            buckets[i] = new ArrayList<>(bucketSize);
        }

        for (int num : nums) {
            buckets[(num - min) / bucketSize].add(num);
        }

        int idx = 0;
        for (int i = 0; i < buckets.length; ++i) {
            //省事儿不再桶排序了
            Collections.sort(buckets[i]);
            for (int j : buckets[i]) {
                nums[idx++] = j;
            }
            //继续递归桶排序
            // if (bucketSize == 1) {
            //     for (int i : bucket) {
            //         res[idx++] = i;
            //     }
            // } else {
            //     //再次递归调用桶排序。做题的时候可以直接用别的排序了。
            //     // if (bucketCnt == 1) {
            //     //     bucketSize--;
            //     // }
            //     // List<Integer> temp = sort(bucketArr.get(i), bucketSize);
            //     // for (int j = 0; j < temp.size(); j++) {
            //     //     resultArr.add(temp.get(j));
            //     // }
            //     Collections.sort(bucket);
            //     for (int i : bucket) {
            //         res[idx++] = i;
            //     }
            // }
        }
    }

    
    /**
     * 基数排序
     * 如果有负数的情况,想到几种处理方式:
     * 1.数组右移,整体变成非负数,可能会越界。
     * 2.多开10个桶,20个桶一起比较
     * 3.只开10个桶,正负分开处理。
     */
    public static void radixSort(int[] nums) {
        int len = nums.length;

        int max = Integer.MIN_VALUE;
        for (int num : nums) {
            max = Math.max(max, num);
        }
        int time = (max + "").length();

        List<Integer>[] buckets = new List[10];
        for (int i = 0, n = 1; i < time; ++i, n *= 10) {
            for (int num : nums) {
                int tmp = num / n % 10;
                if (buckets[tmp] == null) {
                    buckets[tmp] = new ArrayList<>();
                }
                buckets[tmp].add(num);
            }
            int idx = 0;
            for (List<Integer> bucket : buckets) {
                if (bucket == null || bucket.isEmpty()) continue;
                for (int j : bucket) {
                    nums[idx++] = j;
                }
            }
        }
    }

    public static void main(String[] args) {
        int[] arr = {-1, -10, 907, 3, 888, 666, 666, 907};
        for (int j : arr) {
            System.out.print(j + " ");
        }
        System.out.println();

        quickSort(arr, 0, arr.length - 1);

        for (int j : arr) {
            System.out.print(j + " ");
        }
    }
}

参考

排序总结

posted on 2022-08-03 18:06  茶倌  阅读(47)  评论(0)    收藏  举报