在JavaScript中快速排序

时间:2017-10-26 23:22:42

标签: javascript quicksort insertion-sort

我有这个工作插入排序javascript代码。

format

我需要类似于quciksort的东西,但我不知道该怎么做。请有人帮帮我吗?

4 个答案:

答案 0 :(得分:1)

这可能是较晚的帖子,但是我希望这可以对某人有所帮助。 QuickSort是分而治之算法。它选择一个元素作为枢轴,并围绕拾取的枢轴对给定数组进行分区。您可以通过以下方式选择枢轴。 a)选择第一个元素作为枢轴(如下所示)b)选择最后一个元素作为枢轴c)选择一个随机元素作为枢轴。d)选择中值作为枢轴。 如果您的数组已经排序,则时间复杂度将为O(n ^ 2),但对于一般情况和最佳情况而言,则为O(N log N)。它是就地算法并且不稳定(因为分区执行远程交换之一)。在某些情况下,快速排序可能需要花费二次时间。即使对于尺寸小于10-20的微型阵列,Quicksort也会有更多开销。如果对较小的数组使用插入排序,则可以将处理时间减少15-20%。在下面共享我的代码,同样,如果您想减少更多处理时间,请尝试将分区元素估计为数组的中间。

class QuickSort{
	constructor(){
		this.cutoff = 10;
	}
	partition(arr, lo, hi){
		let i = lo, j = hi+1;
		debugger;
		while(true){
			while(arr[++i] < arr[lo]) if(i == hi) break;
			while(arr[lo] < arr[--j]) if(j == lo) break;
			if(i >= j) break; 
			this.swap(arr, i, j);
		}
		 this.swap(arr, lo, j);
		 return j;
	}
	swap(arr, i, j){
		let temp = arr[i];
		arr[i] = arr[j];
		arr[j] = temp;
	}
	sort(arr, lo, hi){
		//if(hi <= lo) return;
		if((this.cutoff + lo) -1 >= hi){
			let insertionSort = new InsertionSort();
			insertionSort.sort(arr); return;		
		}
		console.log('Inside Quick Sort');
		let j = this.partition(arr, lo, hi);
		this.sort(arr, lo, j-1);
		this.sort(arr, j+1, hi);
	}
	shuffle(arr) {
		let n = arr.length;
		for (let i = 0; i < n; i++) {
			// choose index uniformly in [0, i]
			let r =  Math.floor(Math.random() * (i + 1));
			this.swap(arr, i, r);
		}
		console.log('After uniform random Shuffle');
		console.log(arr);
		this.sort(arr, 0, n-1);
	}
}

class InsertionSort{
	constructor(){
		this.quickSort = new QuickSort();
	}
	sort(arr){
		console.log("Inside Insertion sort");
		for(let i = 1; i < arr.length; i++){
		   for(let j = i; j > 0; j--){
			if(arr[j-1] > arr[j]){
				this.quickSort.swap(arr, j, j-1);
			}
			}
			
		}    
	}
}

let arr = [101, 22,4,22,2,7,9,10,49,101,-1,4,1,6,99];
console.log('Before sorting an array');
console.log(arr);
let quickSort = new QuickSort();
quickSort.shuffle(arr);
console.log('After Sorting an array');
console.log(arr);

您可以通过本文time complexity

了解时间的复杂性

答案 1 :(得分:0)

Wikipedia article on Quick Sort非常彻底,甚至包括一些伪代码实现。

维基百科总结了这样的问题:

  

Quicksort是一种分而治之的算法。 Quicksort首先划分了一个   大数组成两个较小的子阵列:低元素和高元素   元素。 Quicksort然后可以递归地对子数组进行排序。

     

步骤如下:

     
      
  1. 从数组中选择一个名为pivot的元素。
  2.   
  3. 分区:对数组进行重新排序,使得值小于枢轴的所有元素都在枢轴之前,而所有值大于枢轴的元素都在它之后(相等的值可以是任意一种)。在此分区之后,枢轴处于其最终位置。这称为分区操作。
  4.   
  5. 递归地将上述步骤应用于具有较小值的元素的子数组,并分别应用于具有较大值的元素的子数组。
  6.         

    递归的基本情况是大小为零或一的数组,按定义按顺序排列,因此它们永远不需要排序。

         

    枢轴选择和分区步骤可以在几个中完成   不同的方法;大大地选择具体的实施方案   影响算法的性能。

只是单挑,我记得当我在学校做这个问题时,一个一个错误是这个问题最头痛的问题,所以如果你没有立即得到正确的答案,请仔细检查你的支点选择和分区逻辑。

答案 2 :(得分:0)

你应该在发布问题之前检查谷歌:Quicksort是一种非常常见的算法,你有足够的资源来描述它。

function swap(items, firstIndex, secondIndex){
    var temp = items[firstIndex];
    items[firstIndex] = items[secondIndex];
    items[secondIndex] = temp;
}


function partition(items, left, right) {

    var pivot   = items[Math.floor((right + left) / 2)],
        i       = left,
        j       = right;


    while (i <= j) {

        while (items[i] < pivot) {
            i++;
        }

        while (items[j] > pivot) {
            j--;
        }

        if (i <= j) {
            swap(items, i, j);
            i++;
            j--;
        }
    }

    return i;
}


function quickSort(items, left, right) {

    var index;

    if (items.length > 1) {

        left = typeof left != "number" ? 0 : left;
        right = typeof right != "number" ? items.length - 1 : right;

        index = partition(items, left, right);

        if (left < index - 1) {
            quickSort(items, left, index - 1);
        }

        if (index < right) {
            quickSort(items, index, right);
        }

    }

    return items;
}

// first call
var result = quickSort(items);

代码信用:N.C.Zakas

此外,请注意,在数组&gt;上调用 Array.prototype.sort()时,V8会使用Quicksort。 10项(V8 source)。在较小的数组上,InsertionShort实际上更快。

答案 3 :(得分:0)

这是用纯JS编写的快速排序的简短版本!

Intro To Algorithms

中所示
$(document).ready(function(){

    $("p").click(function() {
    
    	var varIDeferred = $.Deferred();
        var varJDeferred = $.Deferred();
        
        /*
        var loopJInside = function(j) {  
            console.log("j is : " + j);
            $("span").html($("span").html() + "<br>j is : " + j);
            varJDeferred.resolve();
            j++;
            console.log("j value after incr is : " + j);
            return j;
        }
        
        // call inside loopJ
        setTimeOut(j = loopJInside(j), 500);
        */
        
        var loopJ = function(valueI) {
        
            for (var j = valueI; j < (3+valueI); ) {
        	    
        	varJDeferred = $.Deferred();
                $("span").html($("span").html() + "<br>j is : " + j);
                j++;
                varJDeferred.resolve();
                
            }
            
            varIDeferred.resolve();
            
            return (valueI+1);
        };
        
       	for(var i = 0; i < 3; ) {
       	    
       	    varIDeferred = $.Deferred();
       	    
	    $("span").html($("span").html() + "<br>value of i is : " + i);
            
            if (i == 3)
                break;
            	
            i = loopJ(i);
        };
        
    });
});

也在我的GitHub