常见算法及排序

算法题

斐波拉契数列

    function  f(n) {
        if (n == 0 || n == 1) {
            return n;
        }
        else {
            return f(n-1) + f(n - 2);
        }
    }

1.冒泡排序

好、中、坏:O(n)、O(n2)、O(n2)

function bubbleSort(arr) {
    var len = arr.length;
    var temp;

    for (var i = 0; i < len; i++) {
        for (var j = 0; j < len - 1 - i; j++) {  // 对第一个元素冒泡,这样一趟下来,最大的会排到最后面
            if (arr[j] > arr[j+1]) {        //相邻元素两两对比
                temp = arr[j+1];        //元素交换
                arr[j+1] = arr[j];
                arr[j] = temp;
            }
        }
    }
    return arr;
}

2.选择排序 (每一趟都选择最小元素与当前比较元素交换位置)

好 中 坏 : O(n2)、O(n2)、O(n^2)

    function selectionSort(arr) {
        var temp;
        var len = arr.length;

        for (var i = 0; i < len - 1; i++) {
            var 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;
        }
        return arr;
    }

3.插入排序()( )( )

好、平、坏:O(n2)、O(n)、O(n2)

    function insertSort(arr) {
        var temp, i;
        var len = arr.length;

        for (var j = 1; j < len; ++j) {
            temp = arr[j];
            i = j;
            while (i > 0 && (arr[i - 1] >= temp)) {
                arr[i] = arr[i - 1];
                --i;
            }
            arr[i] = temp;
        }

        return arr;
    }

4.希尔排序

好 中 坏 : O(n1.3)、O(nlogn)-O(n2)、O(n^2)

function shellSort(arr) {
    var len = arr.length,
        temp,
        gap = 1;
    while(gap < len/3) {          //动态定义间隔序列
        gap = gap*3+1;
    }
    for (gap; gap > 0; gap = Math.floor(gap/3)) {
        for (var i = gap; i < len; i++) {
            temp = arr[i];
            for (var j = i-gap; j >= 0 && arr[j] > temp; j -= gap) {
                arr[j+gap] = arr[j];
            }
            arr[j+gap] = temp;
        }
    }
    return arr;
}

5.归并排序

好、平、坏:O(nlogn)、O(nlogn)、O(nlogn)

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 = [];
    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());
    return result;
}

6.快速排序

好、平、坏:O(nlogn)、O(nlogn)、O(n^2)

    function qSort(arr) {
        var len = arr.length;

        if (len == 0) {
            return [];
        }
        var left = [];
        var right = [];
        var flag = arr[0];
        for (var i = 1; i < len; i++) {
            if (arr[i] < flag) {
                left.push(arr[i]);
            }
            else {
                right.push(arr[i]);
            }
        }
        return qSort(left).concat(flag, qSort(right));
    }

///////////////////////////////////////////////////////
    var arr = [2,1,3,4,3];
    var m = qSort(arr);
    console.log(m);  //[1, 2, 3, 3, 4]

7.堆排序

1.它是选择排序的一种。
2.可以利用数组的特点快速定位指定索引的元素。
3.堆分为大根堆和小根堆,是完全二叉树。
4.大根堆的要求是每个节点的值都不大于其父节点的值,即A[PARENT[i]] >= A[i]。在数组的非降序排序中,需要使用的就是大根堆,因为根据大根堆的要求可知,最大的值一定在堆顶。


function buildMaxHeap(arr) {   //建立大顶堆
    len = arr.length;
    for (var i = Math.floor(len/2) - 1; i >= 0; i--) {
        heapify(arr, i);
    }
}

function heapify(arr, i) {     //堆调整
    var left = 2 * i + 1,
        right = 2 * i + 2,
        largest = i;

    if (left < len && arr[left] > arr[largest]) {
        largest = left;
    }

    if (right < len && arr[right] > arr[largest]) {
        largest = right;
    }

    if (largest != i) {
        swap(arr, i, largest);
        heapify(arr, largest);
    }
}

function swap(arr, i, j) {
    var temp = arr[i];
    arr[i] = arr[j];
    arr[j] = temp;
}

function heapSort(arr) {
    buildMaxHeap(arr);

    for (var i = arr.length-1; i > 0; i--) {
        swap(arr, 0, i);
        len--;
        heapify(arr, 0);
    }
    return arr;
}

var arr=[91,60,96,13,35,65,46,65,10,30,20,31,77,81,22];
console.log(heapSort(arr));//[10, 13, 20, 22, 30, 31, 35, 46, 60, 65, 65, 77, 81, 91, 96]

BST遍历

// 中序:
    function inOrder(node) {
        if (!(node == null)) {
            inOrder(node.left);
            putstr(node.show() + " ");
            inOrder(node.right);
            }
    }

// 先序:
    function preOrder(node) {
        if (!(node == null)) {
            putstr(node.show() + " ");
            preOrder(node.left);
            preOrder(node.right);
        }
    }

// 后序:
    function postOrder(node) {
        if (!(node == null)) {
            postOrder(node.left);
            postOrder(node.right);
            putstr(node.show() + " ");
        }
    }

DFS&BFS

// 深度优先遍历
    function dfs(v) {
        this.marked[v] = true;
        for each(var w in this.adj[v]) {
            if (!this.marked[w]) {
                this.dfs(w);
            }
        }
    }

// 广度优先遍历
    function bfs(s) {
        var queue = [];
        this.marked[s] = true;
        queue.push(s); // 添加到队尾
        while (queue.length > 0) {
            var v = queue.shift(); // 从队首移除
            if (v == undefined) {
                print("Visisted vertex: " + v);
            }
            for each(var w in this.adj[v]) {
                if (!this.marked[w]) {
                    this.edgeTo[w] = v;
                    this.marked[w] = true;
                    queue.push(w);
                }
            }
        }
    }

二分搜索算法

    function binSearch(arr, data) {
        var low = 0;
        var high = arr.length-1;

        while (low <= high) {
            var mid = Math.floor((high + low) / 2);
            if (data < arr[mid]) {
                high = mid - 1;            }
            else if (data > arr[mid]) {
                low = mid + 1;
            }
            else {
                return mid;
            }
        }
        return -1;
    }

不借助临时变量,进行两个整数的交换

输入 a = 2, b = 4 输出 a = 4, b =2
这种问题非常巧妙,需要大家跳出惯有的思维,利用 a , b进行置换。
主要是利用 + – 去进行运算,类似 a = a + ( b – a) 实际上等同于最后 的 a = b;

function swap(a , b) {  
  b = b - a;
  a = a + b;
  b = a - b;
  return [a,b];
}

随机生成指定长度的字符串

实现一个算法,随机生成指制定长度的字符窜。
比如给定 长度 8  输出 4ldkfg9j

function randomString(n) {  
  let str = 'abcdefghijklmnopqrstuvwxyz9876543210';
  let tmp = '',
      i = 0,
      l = str.length;
  for (i = 0; i < n; i++) {
    tmp += str.charAt(Math.floor(Math.random() * l));
  }
  return tmp;
} 

实现类似getElementsByClassName 的功能

自己实现一个函数,查找某个DOM节点下面的包含某个class的所有DOM节点?不允许使用原生提供的 getElementsByClassName querySelectorAll 等原生提供DOM查找函数。

function queryClassName(node, name) {  
  var starts = '(^|[ 

	f])',
       ends = '([ 

	f]|$)';
  var array = [],
        regex = new RegExp(starts + name + ends),
        elements = node.getElementsByTagName("*"),
        length = elements.length,
        i = 0,
        element;
 
    while (i < length) {
        element = elements[i];
        if (regex.test(element.className)) {
            array.push(element);
        }
 
        i += 1;
    }
 
    return array;
}
原文地址:https://www.cnblogs.com/Yfling/p/6628371.html