归并排序的引入

得我们去实现一下归并排序, 比较它和其他排序算法的执行效率。

自底向上的排序方法

为一组只有一个元素的数组。 然后通过创建一组左右子数组将它们慢慢合并起来, 每次合并都保存一部分排好序的数据, 直到最后剩下的这个数组所有的数据都已完美排序。 下图演示了自底向上的归并排序算法如何运行的。

代码测试:

1.所调用的函数:

function CArray(numElements) {
    this.dataStore = [];
    this.toString = toString;   this.numElements = numElements;
   this.setData = setData;                 //随机生成一组数
    this.mergeSort=mergeSort;
    this.mergeArrays=mergeArrays;
    for (var i = 0; i < numElements; ++i) {
       this.dataStore[i] = i;
    }
 }function setData() {
    for (var i = 0; i < this.numElements; ++i) {
       this.dataStore[i] = Math.floor(Math.random() * 
                           (this.numElements+1));
    }
 }function toString() {
    var retstr = "";
    for (var i = 0; i < this.dataStore.length; ++i) {
       retstr += this.dataStore[i] + " ";
       if (i > 0 && i % 10 == 0) {
          retstr += "\n";
       }
    }
    return retstr;
 }
function mergeSort() {
         if (this.dataStore.length < 2) {
         return;
         } 
         var step = 1;
         var left, right;
         while (step < this.dataStore.length) {
         left = 0;
         right = step;
         while (right + step <= this.dataStore.length) {
         mergeArrays(this.dataStore, left, left+step, right, right+step);
         left = right + step;
         right = left + step;
         } 
         if (right < this.dataStore.length) {
         mergeArrays(this.dataStore, left, left+step, right, this.dataStore.length);
         } 
         step *= 2;
     }
 }

function mergeArrays(arr,startLeft, stopLeft, startRight, stopRight) {
         var rightArr = new Array(stopRight - startRight + 1);
         var leftArr = new Array(stopLeft - startLeft + 1);
         k = startRight;
         for (var i = 0; i < (rightArr.length-1); ++i) {
         rightArr[i] = arr[k];
         ++k;
         } k
         = startLeft;
         for (var i = 0; i < (leftArr.length-1); ++i) {
         leftArr[i] = arr[k];
         ++k;
         } 
         rightArr[rightArr.length-1] = Infinity; // 哨兵值
         leftArr[leftArr.length-1] = Infinity; // 哨兵值
         var m = 0;
         var n = 0;
         for (var k = startLeft; k < stopRight; ++k) {
         if (leftArr[m] <= rightArr[n]) {
         arr[k] = leftArr[m];
         m++;
         } 
         else {
         arr[k] = rightArr[n];
         n++;
         }
         } 
         alert("left array - ", leftArr[m]);
         alert("right array - ", rightArr[n]);
         }



说明:函数中的关键点就是 leftArr 的, 因为它在对小数组进行排序时不需要花费太多时间。 合并之所以高效, 还有一个原因, 由于未合并的数据已经是排好序的, 将它们合并到一个有序数组的过程非常容易
测试

var nums = new CArray(10);
nums.setData();
alert(nums.toString());
nums.mergeSort();
alert(nums.toString());