• 排序算法小结


    排序算法

    1. 快速排序

    排序数组

    递归法

    public void sort(int[] nums, int l, int r){
        if(l < r) {
            int i = l, j = r, x = nums[l];
            while(i < j) {
                while(i < j && nums[j] >= x) j--;
                nums[i] = nums[j];
                while(i < j && nums[i] <= x) i++;
                nums[j] = nums[i];
            }
            nums[i] = x;
            sort(nums, l, i-1);
            sort(nums, i+1, r);
        }
    }
    

    非递归法

    private static int partition(int[] nums, int start, int end)
    {
        int pivot = nums[start];
        while (start < end) {
            while (start < end && nums[end] >= pivot)
                end--;
            nums[start] = nums[end];
            while (start < end && nums[start] <= pivot)
                start++;
            nums[end] = nums[start];
        }
        nums[start] = pivot;
        return start;
    }
    
    public static void sort(int[] nums, int start, int end)
    {
        Stack<Integer> stack = new Stack<>();
        stack.push(start);
        stack.push(end);
        while(!stack.isEmpty())
        {
            int right = stack.pop();
            int left = stack.pop();
            int mid = partition(nums, left, right);
            if(left < mid-1)
            {
                stack.push(left);
                stack.push(mid-1);
            }
            if(mid+1 < right)
            {
                stack.push(mid+1);
                stack.push(right);
            }
        }
    }
    

    排序链表

    1. 仅交换值

    public void partition(ListNode head, ListNode tail){
        if(head == tail || head.next == tail)
            return head;
        ListNode left = head, curr = head.next;
        int pivot = head.val;
        
        while(curr != tail){
            if(curr.val < pivot){
            	left = left.next;
                swap(left, curr);
            }
            curr = curr.next;
        }
        swap(head, left);
        partition(head, left);
        partition(left.next, tail);
    }
    
    void swap(ListNode n1, ListNode n2){
    	int tmp = n1.val;
        n1.val = n2.val;
        n2.val = tmp;
    }
    

    2. 节点交换

    public ListNode partition(ListNode head){
    	if(head == null || head.next == null)
            return head;
        ListNode ls = new ListNode(0), l = ls, rs = new ListNode(0), r = rs, curr = head;
        int pivot = head.val;
        while(curr != null){
        	if(curr.val < pivot){
            	l.next = curr;
                l = l.next;
            }
            else{
            	r.next = curr;
                r = r.next;
            }
            curr = curr.next;
        }
        l.next = rs.next;
        r.next = null;
        
        ListNode right = partition(head.next);
        head.next = null;
        ListNode left = partition(ls.next);
        
        curr = left;
        while(curr.next != null)
            curr = curr.next;
        curr.next = right;
        return left;
    }
    

    2. 堆排序

    排序数组

    public void sort(int[] nums){
    	int len = nums.length();
        for(int i = len/2-1; i >= 0; i--){
        	adjust(nums, i, len);
        }
        for(int i = len-1; i > 0; i--){
        	swap(nums, 0, i);
            adjust(nums, 0, i);
        }
    }
    
    private void adjust(int[] nums, int i, int len){
    	int tmp = nums[i];
        for(int k = 2*i+1; k < len; k = 2*k+1){
        	if(k+1 < len && nums[k+1] > nums[k]){
            	k++;
            }
            if(tmp < nums[k]){
            	swap(nums, i, k);
                i = k;
            }
            else break;
        }
    }
    
    private void swap(int[] nums, int i, int j){
    	int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    

    3. 冒泡排序

    实现

    public void sort(int[] nums) {
    	int len = nums.length;
        boolean flag;
        for(int i = len - 1; i > 0; i--) {
        	flag = true;
            for(int j = 0; j < i; j++) {
            	if(nums[i] > nums[i + 1]) {
                	swap(nums, i, i + 1);
                    flag = false;
                }
            }
            if(falg) break;
        }
    }
    
    private void swap(int[] nums, int i, int j) {
    	int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    

    时间复杂度:最好: O(n) ,最差: O(n^2) 。
    稳定性:稳定。


    4. 选择排序

    实现

    public void sort(int[] nums) {
    	int len = nums.length;
        int min;
        for(int i = 0; i < len; i++) {
        	min = i;
            for(int j = i + 1; j < len; j++) {
            	min = nums[j] < nums[min] ? j : min;
            }
            if(min != i)
                swap(nums, i, min);
        }
    }
    
    private void swap(int[] nums, int i, int j) {
    	int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    

    时间复杂度: O(n^2) 。
    稳定性:不稳定。


    5. 插入排序

    实现

    public void sort(int[] nums) {
    	int len = nums.length;
        for(int i = 1; i < len; i++) {
        	for(int j = i; j > 0 && nums[j] < nums[j - 1]; j--)
                swap(nums, j - 1, j);
        }
    }
    
    private void swap(int[] nums, int i, int j) {
    	int tmp = nums[i];
        nums[i] = nums[j];
        nums[j] = tmp;
    }
    

    时间复杂度:最好: O(n) ,最差: O(n^2) 。
    稳定性:稳定。


    6. 希尔排序

    实现

    public void sort(int[] nums) {
    	int len = nums.length, gap = len;
        while(true) {
        	gap /= 2;
            for(int i = 0; i < gap; i++) {
            	for(int j = i + gap; j < len; j += gap) {
                	int tmp = nums[j];
                    int k = j - gap;
                    while(k >= 0 && nums[k] > tmp) {
                    	nums[k + gap] = nums[k];
                        k -= gap;
                    }
                    nums[k + gap] = tmp;
                }
            }
            if(gap == 1) break;
        }
    }
    

    时间复杂度:最坏: O(n^2) 。
    稳定性:不稳定。


    7. 归并排序

    实现

    public int[] sort(int[] nums, int l, int r) {
    	if(l == r) return new int[]{nums[l]};
        int mid = l + (r - l) / 2;
        int[] left = sort(nums, l, mid);
        int[] right = sort(nums, mid + 1, r);
        int[] newArr = new int[left.length + right.length);
        int i = 0, j = 0, k = 0;
        while(i < left.length && j < right.length)
        	newArr[k++] = left[i] < right[j] ? left[i++] : right[j++];
        while(i < left.length)
        	newArr[k++] = left[i++];
        while(j < right.length)
            newArr[k++] = right[j++];
        return newArr;
    }
    

    时间复杂度: O(nlog n) 
    空间复杂度: O(n) 
    稳定性:稳定。

  • 相关阅读:
    vsftpd 启动 vsftpd:500 OOPS: bad bool value in config file for: guest_enable
    Vsftpd服务传输文件(转)
    搭建FTP服务
    sed命令
    创建服务类脚本
    jvm 方法区
    B+与B-树
    适配器模式
    java 垃圾回收总结(可达性分析 引用分类
    HBase常见问题答疑解惑【持续更新中】
  • 原文地址:https://www.cnblogs.com/truestoriesavici01/p/13662872.html
Copyright © 2020-2023  润新知