常用算法的javascript实现

常用算法的javascript实现

a) 用双栈实现一个队列结构。利用栈的pop和push操作实现队列的入队和出队操作。要求代码中尽量尝试使用JS类的高级特性和ES6标准语法。

此题涉及队列这种数据结构,之前对这种数据结构有一些了解,会用c语言磕磕碰碰的实现,在这道题中,尤其强调运用js的高级特性,简单的查了查,大致的总结了一下js的高级特性,部分如下

  • array的方法
    1.slice方法:slice(start, end)用来取得原始数组的子数组。其中参数 start和 end都可以是负数。如果是负数的话,实际使用的值是参数的原始值加上数组的长度。如 var array = [2, 3, 4, 5];array.slice(-2, -1);等价于 array.slice(2, 3)。
    2.splice方法:它可以同时删除和添加元素。该方法的第一个参数表示要删除的元素的起始位置,第二个参数表示要删除的元素个数,其余的参数表示要添加的元素。如代码 var array = [2, 3, 4, 5]; array.splice(1, 2, 6, 7, 8);执行之后,array中的元素为 [2, 6, 7, 8, 5]。该方法的返回被删除的元素。
    • arguments
      模拟重载即允许出现名称相同但是形式参数不同的方法,附一段示例代码
1
2
3
4
5
6
7
8
9
10
function sayHello() { 
switch (arguments.length) {
case 0: return "Hello";
case 1: return "Hello, " + arguments[0];
case 2: return (arguments[1] == "cn" ? " 你好," : "Hello, ") + arguments[0];
};
}
sayHello(); // 结果是 "Hello"
sayHello("Alex"); // 结果是 "Hello, Alex"
sayHello("Alex", "cn"); // 结果是 " 你好,Alex"
  • 闭包
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    function addBy(first) { 
    function add(second) {
    return first + second;
    }
    return add;
    }

    var func = addBy(10);
    func(20); // 结果为 30
    var newFunc = addBy(30);
    newFunc(20); // 结果为 50

原文分析:首先 addBy(10)被调用。由于 addBy是在全局代码中声明的,因此被调用时候的执行上下文对应的作用域链只包含全局对象。在 addBy的方法体中,声明了一个内部 functionadd。add的 [[scope]]属性会在作用域链之前加上 functionaddBy的激活对象。该对象中包含了经过初始化的参数 first,其值为 10。至此,functionfunc的 [[scope]]属性的值是包含两个对象。当 func被调用的时候,会进入一个新的执行上下文,而此时的作用域链的前面加上了 functionadd调用时的激活对象。该对象中包含了经过初始化的参数 second,其值为 20。在 func的执行过程中,需要对两个标识符 first和 second求值的时候,会使用之前提到的包含三个对象的作用域链。从而可以正确的求值。
个人理解:就是初始化闭包函数的时候,会初始化外函数的属性值,调用的时候会发现内函数也需要属性值,所以调用时的属性值其实是赋给了内函数。

  • 继承….

  • 还有很多,我不copy了(/黑脸…)
    参考链接 js高级特性

总之,看了一圈,并不知道如何在队列的数据结构中用上这些高级特性 ,觉得靠简单的for&if语句即可可以实现此结构,so….code如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
function Stack() {
var item = [];
this.push = function(node) {
item.push(node);
};
this.pop = function() {
return item.pop();
}
this.isEmpty = function() {
return item.length === 0;
}
}

var stack1 = new Stack();
var stack2 = new Stack();

function push(node) {
stack1.push(node);
}

function pop() {
if (stack1.isEmpty() && stack2.isEmpty()) {
throw new Error("Queue is empty");
}
if (stack2.isEmpty()) {
while (!stack1.isEmpty()) {
stack2.push(stack1.pop());
}
}

return stack2.pop();

}

b) 实现快速排序和二路归并排序算法。
(要求搭建node.js环境运行javascript代码,尝试学会js代码调试)

之前有搭过node.js环境,用c语言写过这两种排序,改改应该就可以了,所以这题就很省事(/微笑)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
//快排
function quickSort(arr) {
function swap(arr, a, b) {
var temp = arr[a];
arr[a] = arr[b];
arr[b] = temp;
}

function partition(arr, left, right) {
var pivot = arr[right]; //初始值先将基准设置为最后一位
var storeIndex = left;
for (var i = left; i < right; i++) {
if (arr[i] < pivot) {
swap(arr, storeIndex, i);
storeIndex++;
}
}
swap(arr, right, storeIndex);
return storeIndex;
}

function sort(arr, left, right) {
if (left > right) return;

var storeIndex = partition(arr, left, right);
sort(arr, left, storeIndex - 1);
sort(arr, storeIndex + 1, right);
}

sort(arr, 0, arr.length - 1);
return arr;
}
var arr = [5, 67, 43, 13, 5, 23, 53];
console.log(quickSort(arr));
//归并
function merge(left, right) {
var tmp = [];

while (left.length && right.length) {
if (left[0] < right[0])
tmp.push(left.shift());
else
tmp.push(right.shift());
}

return tmp.concat(left, right);
}

function mergeSort(a) {
if (a.length === 1)
return a;

var mid = a.length / 2,
left = a.slice(0, mid),
right = a.slice(mid);

return merge(mergeSort(left), mergeSort(right));
}
console.log(mergeSort([1, 3, 4, 2, 5, 0, 8, 10, 4]));