最近在学习es6
所以代码主要使用了es6的一些东西
链表的设计
我们设计链表包含两个类,一个是 Node 类用来表示节点,另一个事 LinkedList 类提供插入节点、删除节点等一些操作。
/**
* 一般的语言实现链表都需要指针来实现
* 而js的引用类型本来就是按值引用的
* 变量中保存的实质上是一个指向其对应对象的一个指针
*/
class Node {
constructor(val) {
this.val = val;
this.next = null;
}
}
class LinkedList { //传入和返回都是Node类型,第一个元素下标0
constructor(node) {
this.head = node;
this.length = 1;
}
get isEmpty(){
return !this.length;
}
append(node){
var lastNode=this.findAsIndex(this.length-1);
lastNode.next=node;
this.length++;
}
insert(index,node){ //在哪个元素之前插入
var targetNode=this.findAsIndex(index-1);
node.next=targetNode.next;
targetNode.next=node;
}
remove(index){
var preNode=this.findAsIndex(index-1);
var nextNode=this.findAsIndex(index+1);
preNode.next=nextNode;
}
findAsIndex(index){
if(index>this.length){
console.log('越界');
return
}
if(index===0){
return this.head;
}
var curNode=this.head;
while(index&&curNode){
index--;
curNode=curNode.next;
}
return curNode;
}
toString(){
var curNode=this.head;
var arr=[];
var i=0;
while(curNode){
arr[i++]=curNode.val;
curNode=curNode.next;
}
return arr.toString();
}
}
let list=new LinkedList(new Node('a'));
list.append(new Node('b'));
list.append(new Node('d'));
list.insert(2,new Node('c'));
list.remove(1);
console.log(list.toString())
队列简单的实现ES5版本
function Queue(item) {
this.items = item || [];
}
Queue.prototype = {
constructor: Queue,
enqueue: function (node) {
return this.items.push(node)
},
dequeue: function (node) {
return this.items.shift(node)
},
get size() {
return this.items.length
},
get isEmpty() {
return !this.items.length
}
}
function LoopQueue() {
Queue.call(this);
}
LoopQueue.prototype = Object.create( Queue.prototype)
var loopQ = new LoopQueue();
loopQ.enqueue('SkyRover')
loopQ.enqueue('Even')
loopQ.enqueue('Alice')
console.log(loopQ)
树
树的基本概念
- 结点
- 结点的度
结点所拥有的分支数目,如结点7的度为2 - 叶子(终端结点)
- 树的深度
树中结点的最大层次称为树的深度,如上图树的深度为4 - 森林
m(m>=0)棵互不相交树的集合称为森林
二叉树
二叉树中的结点最多只能有两个子结点:一个是左侧子结点,另一个是右侧子结点。
二叉树的基本运算
- 创建一棵二叉树
- 显示一棵二叉树
- 按先序遍历(根、左、右)二叉树上所有结点
- 按中序遍历(左、根、右)二叉树上所有结点
- 按后序遍历(右、根、左)二叉树上所有结点
- 按层次遍历二叉树上所有结点
- 求二叉树叶子结点数目
- 求二叉树结点数目
- 求二叉树深度
二叉树性质
- 在二叉树的第i层上至多有 2^(i-1)个结点
- 深度为h的二叉树中至多有2^(h-1)个结点
- 对任意一棵二叉树T,如果其叶子结点数为n0,度为2的结点数为n2,则有n0=n2+1;
- 具有n个结点的完全二叉树的深度为log2n - 1
- 如果一棵有n个结点的完全二叉树(其深度为log2n - 1)的结点按层次(从第1层到log2n - 1层),每层从左到右,则对任一结点i(1<=i<=n)有:
如果i等于1 结点i是根节点,无双亲;
如果i>1在,则双亲结点是结点i/2;
如果2i>n,则结点i无左侧子结点,该结点为叶子结点;否则其左侧子结点为2i;
如果2i+1>n,则结点i无右侧子结点,该结点为叶子结点;否则其右侧子结点为2i+1;
具体实现
class Node {
constructor(key, left = null, right = null) {
this.key = key;
this.left = left;
this.right = right;
}
}
class BinarySearchTree {
constructor(node) {
this.root = node;
}
insert(newNode, node = this.root) {
if (!this.root) {
this.root = newNode;
} else {
if (newNode.key < node.key) {
if (node.left === null) {
node.left = newNode;
} else {
this.insert(newNode, node.left);
}
} else {
if (node.right === null) {
node.right = newNode
} else {
this.insert(newNode, node.right)
}
}
}
}
preOrderTraverse(curNode = this.root) { //可以从指定结点进行
if (!curNode) {
return
}
var arr = [];
const preOrderTraverseNode = (node) => {
if (!node) {
return
}
arr.push(node.key)
preOrderTraverseNode(node.left);
preOrderTraverseNode(node.right);
}
preOrderTraverseNode(curNode);
return arr;
}
inOrderTraverse(curNode = this.root) {
if (!curNode) {
return
}
var arr = [];
const inOrderTraverseNode = (node) => {
if (!node) {
return
}
inOrderTraverseNode(node.left);
arr.push(node.key)
inOrderTraverseNode(node.right);
}
inOrderTraverseNode(curNode);
return arr;
}
postOrderTraverse(curNode = this.root) {
if (!curNode) {
return
}
var arr = [];
const postOrderTraverseNode = (node) => {
if (!node) {
return
}
postOrderTraverseNode(node.left);
postOrderTraverseNode(node.right);
arr.push(node.key)
}
postOrderTraverseNode(curNode);
return arr;
}
minNode(node = this.root) {
if (!node.left) {
return node.key;
}
return this.minNode(node.left);
}
maxNode(node = this.root) {
if (!node.right) {
return node.key;
}
return this.maxNode(node.right);
}
search(key,curNode=this.root) {
if(!curNode){
return false
}
if(key===curNode.key){
return curNode
}
return this.search(key,key<curNode.key?curNode.left:curNode.right)
}
}
const tree = new BinarySearchTree(new Node(11));
tree.insert(new Node(15))
tree.insert(new Node(7))
tree.insert(new Node(5))
tree.insert(new Node(3))
tree.insert(new Node(9))
tree.insert(new Node(8))
tree.insert(new Node(10))
tree.insert(new Node(13))
tree.insert(new Node(12))
tree.insert(new Node(14))
tree.insert(new Node(20))
tree.insert(new Node(18))
tree.insert(new Node(25))
console.log(tree.preOrderTraverse())
console.log(tree.inOrderTraverse())
console.log(tree.postOrderTraverse())
console.log(tree.minNode());
console.log(tree.maxNode());
console.log(tree.search(9));