Datawhale | 編程第6期 Test 3

排序

1.實現歸併排序、快速排序、插入排序、冒泡排序、選擇排序、堆排序(選做)

歸併排序

function mergeSort(arr) {  //採用自上而下的遞歸方法
    var len = arr.length;
    if(len < 2) {
        return arr;
    }
    var middle = Math.floor(len / 2),
        left = arr.slice(0, middle),
        right = arr.slice(middle);
    return merge(mergeSort(left), mergeSort(right));
}

function merge(left, right)
{
    var result = [];
    console.time('歸併排序耗時');
    while (left.length && right.length) {
        if (left[0] <= right[0]) {
            result.push(left.shift());
        } else {
            result.push(right.shift());
        }
    }

    while (left.length)
        result.push(left.shift());

    while (right.length)
        result.push(right.shift());
    console.timeEnd('歸併排序耗時');
    return result;
}

快速排序

var quickSort2 = function(arr) {
    console.time('2.快速排序耗時');
  if (arr.length <= 1) { return arr; }
  var pivotIndex = Math.floor(arr.length / 2);
  var pivot = arr.splice(pivotIndex, 1)[0];
  var left = [];
  var right = [];
  for (var i = 0; i < arr.length; i++){
    if (arr[i] < pivot) {
      left.push(arr[i]);
    } else {
      right.push(arr[i]);
    }
  }
console.timeEnd('2.快速排序耗時');
  return quickSort2(left).concat([pivot], quickSort2(right));
};

插入排序

function binaryInsertionSort(array) {
    if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
        console.time('二分插入排序耗時:');

        for (var i = 1; i < array.length; i++) {
            var key = array[i], left = 0, right = i - 1;
            while (left <= right) {
                var middle = parseInt((left + right) / 2);
                if (key < array[middle]) {
                    right = middle - 1;
                } else {
                    left = middle + 1;
                }
            }
            for (var j = i - 1; j >= left; j--) {
                array[j + 1] = array[j];
            }
            array[left] = key;
        }
        console.timeEnd('二分插入排序耗時:');

        return array;
    } else {
        return 'array is not an Array!';
    }
}

冒泡排序

function bubbleSort(arr) {
    var len = arr.length;
    for (var i = 0; i < len; i++) {
        for (var j = 0; j < len - 1 - i; j++) {
            if (arr[j] > arr[j+1]) {        //相鄰元素兩兩對比
                var temp = arr[j+1];        //元素交換
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

選擇排序

function selectionSort(arr) {
    var len = arr.length;
    var minIndex, temp;
    console.time('選擇排序耗時');
    for (var i = 0; i < len - 1; i++) {
        minIndex = i;
        for (var j = i + 1; j < len; j++) {
            if (arr[j] < arr[minIndex]) {     //尋找最小的數
                minIndex = j;                 //將最小數的索引保存
            }
        }
        temp = arr[i];
        arr[i] = arr[minIndex];
        arr[minIndex] = temp;
    }
    console.timeEnd('選擇排序耗時');
    return arr;
}

堆排序

/*方法說明:堆排序
@param  array 待排序數組*/
function heapSort(array) {
    console.time('堆排序耗時');
    if (Object.prototype.toString.call(array).slice(8, -1) === 'Array') {
        //建堆
        var heapSize = array.length, temp;
        for (var i = Math.floor(heapSize / 2) - 1; i >= 0; i--) {
            heapify(array, i, heapSize);
        }

        //堆排序
        for (var j = heapSize - 1; j >= 1; j--) {
            temp = array[0];
            array[0] = array[j];
            array[j] = temp;
            heapify(array, 0, --heapSize);
        }
        console.timeEnd('堆排序耗時');
        return array;
    } else {
        return 'array is not an Array!';
    }
}
/*方法說明:維護堆的性質
@param  arr 數組
@param  x   數組下標
@param  len 堆大小*/
function heapify(arr, x, len) {
    if (Object.prototype.toString.call(arr).slice(8, -1) === 'Array' && typeof x === 'number') {
        var l = 2 * x + 1, r = 2 * x + 2, largest = x, temp;
        if (l < len && arr[l] > arr[largest]) {
            largest = l;
        }
        if (r < len && arr[r] > arr[largest]) {
            largest = r;
        }
        if (largest != x) {
            temp = arr[x];
            arr[x] = arr[largest];
            arr[largest] = temp;
            heapify(arr, largest, len);
        }
    } else {
        return 'arr is not an Array or x is not a number!';
    }
}

2.編程實現 O(n) 時間複雜度內找到一組數據的第 K 大元素

function topKMaxOfArr(k, arr) {
  function swap(a, b) {
    var t = arr[a];
    arr[a] = arr[b];
    arr[b] = t;
  }

  var i, j;
  //只需循環k次
  for (i = arr.length; i > arr.length - k; i--) {

    for (j = Math.floor(i / 2) - 1; j >= 0; j--) {
      if (arr[j] < arr[2 * j + 1]) {
        swap(j, 2 * j + 1);
      }
      if (2 * j + 2 < i && arr[j] < arr[2 * j + 2]) {
        swap(j, 2 * j + 2);
      }
    }

    swap(i - 1, 0);
  }

  return arr.slice(arr.length - k);
}

二分查找

1. 實現一個有序數組的二分查找算法

function binarySearch(target, arr) {
  var start = 0;
  var end = arr.length - 1;

  while (start <= end) {
    var mid = parseInt(start + (end - start) / 2);
    if (target == arr[mid]) {
      return mid;
    } else if (target > arr[mid]) {
      start = mid + 1;
    } else {
      end = mid - 1;
    }
  }
  return -1;
}

2. 實現模糊二分查找算法(比如大於等於給定值的第一個元素)

const fuzzyBinarySearch = (nums, target) => {
  let right = 0;
  let left = nums.length - 1;

  while (right < left) {
    let mid = (left + right) / 2;
    if (nums[mid] < target) {
      left = mid + 1;
    } else {
      right = mid - 1;
    }

    if (left > (nums.length - 1)) {
      return -1;
    }

    return left;
  }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章