zoukankan      html  css  js  c++  java
  • js快速排序算法解析

    数组的快速排序算法,和并归排序步骤基本类似。

    都是先拆分,后合并。并归排序是:拆分容易,合并难。 快速排序是:拆分难,合并容易

    要理解快速排序,首先要理解拆分逻辑

    要素:找一个基准点,通过操作使得数列的左边全部都是小于他的数,右边全部都是大于他的数;

    1、选中基准点,开始索引 i   ,结束索引  j

    2、从数列右边开始往左边找,找到比基准点小的,交换位置 i++

    3、从数列左边开始往右边找,找到比基准点大的,交换位置 j--

    4、循环执行2、3,直到,i 不是小于 j

    例如: 有数组  var arr = [30,24,5,58,18,36,12,42,39];

               开始索引  i = 0;  结束索引 j = arr.length-1;    基准点  pivot = arr[i]  即为30

       则有如下代码

          

    var arr = [30,24,5,58,18,36,12,42,39];
    		var i = 0, j = arr.length-1,pivot = arr[i];
    		
    		while(i < j ){  //当最后结束时 i = j
    			//从右往左找,找到比基准点小等的就交换,交换后,基准点的索引变为 j
    			while(i < j && arr[j] > pivot )
    				j--;  //排除已经满足条件的点                        
    			if(i < j ){
    				swap(i++,j,arr);
    			}
    			
    			//从左往右找,找到比基准点大的就交换,交换后,基准点的索引变为 i
    			while(i < j && arr[i] <= pivot)
    				i++; //排除已经满足条件的点
    			if(i < j ){
    				swap(i,j--,arr);
    			}
    		}
    		
    		function swap(a,b,arr){
    			console.log(a,b,arr[a],arr[b])
    			var temp = arr[a];
    			arr[a] = arr[b];
    			arr[b] = temp;
    		}
    	
    		console.log(i,arr); //基准点i,处理好的arr
    

      

    以上代码就是快速排序的核心,如果将数列,不断以上面方式细分,直到分为单个元素。即最后的结果就是一个有序的数列

    下面给出完整代码

    	    var arr = [30,24,5,58,18,36,12,42,39];
    		
    		function Partition(arr,low,high){
    			var i = low,j = high,pivot = arr[i];
    			
    			while(i < j ){
    				//从右往左找
    				while(i < j && arr[j] > pivot )
    					j--;                        
    				if(i < j ){
    					swap(i++,j,arr);
    				}
    				
    				//从左往右找
    				while(i < j && arr[i] <= pivot)
    					i++; 
    				if(i < j ){
    					swap(i,j--,arr);
    				}
    			}
    
    			return i;  //返回基准元素位置
    		}
    		
    		function swap(a,b,arr){
    			console.log(a,b,arr[a],arr[b])
    			var temp = arr[a];
    			arr[a] = arr[b];
    			arr[b] = temp;
    		}
    		
    		function QuickSort(arr,low,high){
    			var mid;
    			if(low < high){
    				mid = Partition(arr,low,high); //返回基准元素位置
    				QuickSort(arr,low,mid-1);   //左边快速排序
    				QuickSort(arr,mid+1,high);  //右边快速排序
    			}
    		}
    		QuickSort(arr,0,arr.length-1);
    		console.log(arr);    
    

      

    优化扩展:

       上面的Partition函数中,不管是从右往左,还是从左往右。都是跟pivot基准元素交换。。实际上,可以先直接左边和右边交换,最后再和基准元素交换,减少交换次数。代码如下

    var arr = [30,24,5,58,18,36,12,42,39];
    		var i = 0, j = arr.length-1,pivot = arr[i];
    		var mid;
    		while(i < j ){  //当最后结束时 i = j
    			//从右往左找
    			while(i < j && arr[j] > pivot )
    				j--;  //排除已经满足条件的点                        
    			//从左往右找
    			while(i < j && arr[i] <= pivot)
    				i++; //排除已经满足条件的点
    			
    			//找到两个点,就相互交换
    			if(i < j ){
    				swap(i++,j--,arr);
    			}
    		}
    		
    		//最后将中间点和基准点交换
    		if(arr[i] > pivot){
    			mid = i-1;
    			swap(0,mid,arr);
    		}else{
    			mid = i;
    			swap(0,mid,arr);
    		}
    		
    		function swap(a,b,arr){
    			console.log(a,b,arr[a],arr[b])
    			var temp = arr[a];
    			arr[a] = arr[b];
    			arr[b] = temp;
    		}
    	
    		console.log(mid,arr); //基准点mid,处理好的arr
    

      

    使用js的数组方法 , unshift 和push

    使用unshift 和push实现,将数列的基准元素,左边全部小于他,右边全部大于他

               var arr = [30,24,5,58,18,36,12,42,39];
    		var i = 0, pivot = arr[0], arr2 = [pivot];
    		for(var j = 1; j < arr.length; j++ ){
    			if(arr[j] > pivot){
    				arr2.push(arr[j]);
    			}else{
    				arr2.unshift(arr[j]);
    				i++;
    			}
    		}
    		console.log(i,arr2);		    
    

      

    使用 unshift和push实现的快速排序

    		
    		var arr = [30,24,5,58,18,36,12,42,39];
    		
    		function Partition(arr,low,high){
    			var i = low,pivot = arr[i];
    			var arr2 = [pivot];
    			for(var j = low+1; j <= high; j++){
    				if(arr[j] > pivot){
    					arr2.push(arr[j]);
    				}else{
    					arr2.unshift(arr[j]);
    					i++;
    				}
    			}
    			j = 0;
    			for(var k = low ; k <= high ; k++){
    				arr[k] = arr2[j++];
    			}
    			return i;  //返回基准元素位置
    		}
    
    		function QuickSort(arr,low,high){
    			var mid;
    			if(low < high){
    				mid = Partition(arr,low,high); //返回基准元素位置
    				QuickSort(arr,low,mid-1);   //左边快速排序
    				QuickSort(arr,mid+1,high);  //右边快速排序
    			}
    		}
    		QuickSort(arr,0,arr.length-1);
    		console.log(arr);
    

      

  • 相关阅读:
    Flex AIR应用GPS定位功能(Android和IOS)
    Flex AIR应用拍照功能(Android和IOS版本)
    读取Flex AIR应用程序设置
    查看本机开放的端口号,查看某个端口号是否被占用,查看被占用的端口号被哪个进程所占用,如何结束该进程
    Eclipse设置默认编码为UTF-8
    Eclipse使用教程之精华篇
    hdu 1829 分组并查集
    hdu 1316高精度
    hdu 4287 字典树问题
    hdu 1867 kmp共工前后缀串问题
  • 原文地址:https://www.cnblogs.com/muamaker/p/9524437.html
Copyright © 2011-2022 走看看