zoukankan      html  css  js  c++  java
  • Java: 实现顺序表和单链表的快速排序

    快速排序

    • 快速排序原理

      快速排序(Quick Sort)的基本思想是,通过一趟排序将待排记录分割成独立的两部分,其中一部分记录的关键字均比另一部分记录的关键字小,则可对这两部分记录继续进行排序,以达到整个序列有序的目的。

    • 主程序
    package Sort;
    
    public class QuickSort {
    	
    	private void Qsort(int[] list, int low, int high){
    		int privot;
    		if(low < high) {
    			print(list);
    			/*算出枢轴值privot*/
    			privot = Partition(list, low, high);
    			/*对低子表递归排序*/
    			Qsort(list, low, privot-1);
    			/*对高子表递归排序*/
    			Qsort(list, privot+1, high);			
    		}
    	}
    	
    	private int Partition(int[] list, int low, int high){
    		/*用表的第一个记录做枢轴记录*/
    		int privotkey = list[low];
    		while (low < high){
    			while (low < high && list[high] > privotkey)
    				high--;			
    			/*将比枢轴记录小的记录交换到低端*/
    			swap(list, low, high);
    			while (low < high && list[low] < privotkey)
    				low++;
    			/*将比枢轴记录大的记录交换到高端*/
    			swap(list, low, high);			
    		}
    		/*返回枢轴所在的位置*/
    		return low;
    	}
    	
    	private void swap(int [] list,int j, int i){
    		int temp;
    		temp = list[i];
    		list[i] = list[j];
    		list[j] = temp;
    	}	
    	
    	private void print(int[] data) {
    		System.out.println("当前list数组的值:");
    		for (int i = 0; i < data.length; i++) {
    			System.out.print(data[i] + "	");
    		}
    		System.out.println();
    	}
    	
    	public static void main(String[] args) {
    		int[] list = {50,40,80,30,60,70,10,90,20};
    		QuickSort qs = new QuickSort();
    		qs.Qsort(list, 0, list.length-1);
    		qs.print(list);
    	}
    }
    

      

    • Qsort()分析
    	private void Qsort(int[] list, int low, int high){
    		int privot;
    		if(low < high) {
    			print(list);
    			/*算出枢轴值privot*/
    			privot = Partition(list, low, high);
    			/*对低子表递归排序*/
    			Qsort(list, low, privot-1);
    			/*对高子表递归排序*/
    			Qsort(list, privot+1, high);			
    		}
    	}
    

      

    • Partition()分析
    	private int Partition(int[] list, int low, int high){
    		/*用表的第一个记录做枢轴记录*/
    		int privotkey = list[low];
    		while (low < high){
    			while (low < high && list[high] > privotkey)
    				high--;			
    			/*将比枢轴记录小的记录交换到低端*/
    			swap(list, low, high);
    			while (low < high && list[low] < privotkey)
    				low++;
    			/*将比枢轴记录大的记录交换到高端*/
    			swap(list, low, high);			
    		}
    		/*返回枢轴所在的位置*/
    		return low;
    	}
    

      

    • 输出结果
    当前list数组的值:
    50	40	80	30	60	70	10	90	20	
    当前list数组的值:
    20	40	10	30	50	70	60	90	80	
    当前list数组的值:
    10	20	40	30	50	70	60	90	80	
    当前list数组的值:
    10	20	30	40	50	70	60	90	80	
    当前list数组的值:
    10	20	30	40	50	60	70	90	80	
    当前list数组的值:
    10	20	30	40	50	60	70	80	90	
    

      

    • 时间复杂度分析

      最优情况下,快速排序算法的时间复杂度为O(nlogn),空间复杂度也为O(nlogn)

    •  单链表快速排序实现
    /**
     * Definition for singly-linked list.
     * public class ListNode {
     *     int val;
     *     ListNode next;
     *     ListNode(int x) { val = x; }
     * }
     */
    public class Solution {
        public ListNode sortList(ListNode head) {
            if(head == null || head.next == null) return head;
            
            ListNode left = new ListNode(0), leftHead = left;
            ListNode right = new ListNode(0), rightHead = right;
            ListNode mid = new ListNode(0), midHead = mid;
            int val = head.val;
            
            while(head != null) {
                if(head.val < val) {
                    left.next = head;
                    left = head;
                } else if(head.val > val) {
                    right.next = head;
                    right = head;
                } else {
                    mid.next = head;
                    mid = head;
                }
                head = head.next;
            }
            
            left.next = null;
            right.next = null;
            mid.next = null;
            return merge(sortList(leftHead.next), midHead.next, sortList(rightHead.next));
        }
        
        public ListNode merge(ListNode left, ListNode mid, ListNode right) {
            ListNode leftTail = getTail(left);
            ListNode midTail = getTail(mid);
            midTail.next = right;
            if(leftTail != null) {
                leftTail.next = mid;
                return left;
            } else {
                return mid;
            }
        }
        
        public ListNode getTail(ListNode head) {
            if(head == null) return head;
            while(head.next != null) {
                head = head.next;
            }
            return head;
        }
    }
    

      

  • 相关阅读:
    js内置数据类型
    vue禁止复制的方式
    阻止element组件中的<el-input/>的粘贴功能
    Vue插件集合
    qs.parse()、qs.stringify()、JSON.stringify() 用法及区别
    es6数组的一些函数方法使用
    文章段落首字母缩进两个字符
    深圳scala-meetup-20180902(3)- Using heterogeneous Monads in for-comprehension with Monad Transformer
    深圳scala-meetup-20180902(2)- Future vs Task and ReaderMonad依赖注入
    深圳scala-meetup-20180902(1)- Monadic 编程风格
  • 原文地址:https://www.cnblogs.com/danbing/p/5148608.html
Copyright © 2011-2022 走看看