我一直在尝试各种排序算法的迭代次数。我一直试图找出哪些需要执行大多数迭代。我将迭代定义为循环迭代或函数执行(为了考虑递归)。在性能方面,快速排序和合并排序似乎比冒泡排序要快得多。如果数组中的项目较少,则快速排序似乎更快。这可能是因为我的快速排序算法效率不高。
我的问题是快速排序比合并排序更少的迭代,如果是这样的话。我还在下面列出了我的代码,以防我的算法不正确。谢谢。
function quickSort(arr){
iter++;
let length = arr.length;
let pivot_index = [length-1]; //Math.floor(Math.random() * [length -1]);
let index = 0;
while(pivot_index>index){
iter++;
if(arr[pivot_index]<arr[index]){
let temp = arr[index];
arr[index] = arr[pivot_index-1];
arr[pivot_index-1] = arr[pivot_index] ;
arr[pivot_index] = temp;
--pivot_index
}
else
++index;
}
if(length>3)
return quickSort(arr.slice(0, pivot_index)).concat([arr[pivot_index]],quickSort(arr.slice(pivot_index+1)));
else
return arr;
}
function selectionSort(arr){
let numIterations = 0;
for(let i = 0; i<arr.length-1; i++){
numIterations+=1;
for(let j = i +1; j<arr.length; j++){
if( arr[i] > arr[j]){
let temp = arr[i];
arr[i] = arr[j];
arr[j] = temp;
}
numIterations+=1;
}
}
return {"num_iterations": numIterations, "arr":arr}
}
function bubbleSort(arr){
let numIterations = 0;
let count = 0;
do{
var swapped = false;
numIterations+=1;
count+=1;
for(let i = 0;i<arr.length-count;i++){
numIterations+=1;
if(arr[i]>arr[i+1]){
let temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
swapped = true;
}
}
} while(swapped == true)
return {"num_iterations": numIterations, "arr":arr}
}
function mergeSort(arr){
iter+=1;
if(arr.length>1){
let divsor = arr.length + 1;
let arr_left_half = arr.slice(0,parseInt(divsor / 2));
let arr_right_half = arr.slice(parseInt( divsor / 2));
arr = null;
var tup_arr = [mergeSort(arr_left_half), mergeSort(arr_right_half)];
}else
return arr;
let l = []
while(tup_arr[0].length > 0 || tup_arr[1].length > 0){
iter+=1;
let arr1_length = tup_arr[0].length;
let arr2_length = tup_arr[1].length;
if(arr1_length > 0 && arr2_length > 0){
if(tup_arr[0][0] > tup_arr[1][0])
l.push(tup_arr[1].shift());
else
l.push(tup_arr[0].shift());
}
else if( arr1_length > 0)
l.push(tup_arr[0].shift());
else if(arr2_length > 0)
l.push(tup_arr[1].shift())
}
tup_arr = null;
return l;
}
let iter = 0;
let arr = []
for(let i =0;i<10000;i++){
let num = Math.floor(Math.random() * 10000);
arr.push(num);
}
let bubble_sort = bubbleSort(arr.slice());
let selection_sort = selectionSort(arr.slice());
let merge_sort = mergeSort(arr.slice());
console.log("Merge Sort Iterations:"+iter);
iter = 0;
let quick_sort = quickSort(arr.slice());
console.log("Quick Sort Iterations:"+iter);
console.log("Selection Sort Iterations:"+selection_sort.num_iterations);
console.log("Bubble Sort Iterations:"+bubble_sort.num_iterations);
答案 0 :(得分:2)
Mergesort总是递归到⌈log2N⌉
深度。在每个递归级别,每个元素都会被比较一次。
Quicksort只有在每次都猜到最佳分区值时才能实现,这不太可能。通常,隔板的一侧将大于另一侧。稍微增加递归深度的平衡是,一旦对分区进行排序,就不再比较其元素。因此,一些元素的比较越多,其他元素的比根据“平均情况”的一个似是而非的定义,快速排序预计将比mergesort进行大约40%的比较。
但是quicksort对于大型数据集具有很大的优势。在mergesort中,合并步骤无法有效地完成。该算法取决于能够使用与原始数据集相同大小的临时存储。
因此,如果您有足够的存储空间,那么mergesort可能会更好。至少那是glibc的作者的判断,除非数据集非常大,否则qsort
实现会进行合并。