JS数据结构和算法、javascript数据结构实现

JS数据结构和算法

后进先出,新元素都靠近栈顶

栈也被用在编程语言的编译器和内存中保存变量、方法调用等,也被用于浏览器历史记录

数组实现

  • 用数组保存栈里的元素

  • 对元素的插入和删除功能进行限制,使其遵循LIFO

  • 实现以下方法

    push pop peek isEmpty clear size

class Stack{
	constructor() {
		this.items = []
	}
	push = el => {
		this.items.push(el)
	}
	pop = () => (
		this.items.pop()
	)
	peek = () => (
		this.items[this.items.length - 1]
	)
	isEmpty = () => (
		this.items.length === 0
	)
	size = () => (
		this.items.length
	)
	clear = () => {
		this.items = []
	}
}

对象实现

class Stack {
  constructor() {
    this.count = 0;
    this.items = {};
  }
  push= element => {
    this.items[this.count] = element;
    this.count++;
    return element;
  }
  size = () => this.count
	isEmpty = () => this.count === 0
	pop = () => {
    if(this.isEmpty()) return undefined;
    this.count--;
		const result = this.items[this.count]
  	delete this.items[this.count]
		return result;
  }
  peek = () => {
    if(this.isEmpty()) return undefined;
    return this.items[this.count - 1];
  }
  clear = () => {
    this.items = {};
    this.count = 0;
  }
  toString = () => {
    if(this.isEmpty()) return '';
    let objString = this.items[0];
    for(let i = 1; i < this.count; i ++) {
      objString = `${objString}, ${this.items[i]}`;
    }
    return objString;
  }
}

JS私有属性

symbol实现

const items = Symbol('stackItems')
class Stack {
	constructor() {
		this[items] = []
	}
	push = el => (
		this[items].push(el)
	)
}

const stack = new Stack()
stack.push(0)
let objectSymbol = Object.getOwnPropertySymbols(stack)
stack[objectSymbols[0]].push(1)

weakMap实现

const items = new WeakMap()
class Stack {
	constructor() {
		items.set(this, [])
	}
	push = el => {
		const s = items.get(this)
		return s.push(el)
	}
	pop = () => {
		const s = items.get(this)
		return s.pop()
	}
}

队列

先进先出

class Queue {
	constructor() {
		this.count = 0 
		this.lowestCount = 0
		this.items = {}
	}
	enqueue = el => {
		this.items[this.count] = el
		this.count ++ 
		return el
	}
	dequeue = () => {
		if(!this.items[this.lowestCount])
			return
		const result = this.items[this.lowestCount]
		delete this.items[this.lowestCount]
		this.lowestCount++
		return result
	}
	peek = () => {
		if(this.isEmpty)
			return undefined
        return this.items[this.lowestCount]
	}
	isEmpty = () => this.count === this.lowestCount
	size = () => this.count - this.lowestCount
	clear = () => {
		this.count = 0
		this.lowestCount = 0
		this.items =  {}
	}
}

双端队列

一种允许从前端和后端添加和移除元素的特殊队列

class Deque {
  constructor() {
    this.count = 0;
    this.lowestCount = 0;
    this.items = {};
  }
  addFront = element => {
    if(this.isEmpty()){
      this.addBack(element)
    } else (this.lowestCount > 0) {
      this.lowestCount--;
      this.items[this.lowestCount] = element
    } else {
      // this.lowestCount === 0
      for(let i=count;i>0;i--) {
        this.items[i]= this.items[i-1]
      }
      this.lowestCount = 0;
      this.items[0] = element;
      this.count++;
    }
  }
  addBack = element => {
    this.items[this.count] = element;
    this.count++;
    return element;
  }
  removeFront = () => {
    if (!this.items[this.lowestCount]) 
      return;
    const result = this.items[this.lowestCount];
    delete this.items[this.lowestCount];
    this.lowestCount++;
    return result;
  }
  removeBack = () => {
  }
  peekFront = () => {
    if (this.isEmpty) return void 0;
    return this.items[this.lowestCount];
  }
  peekBack = () => {
    if (this.isEmpty) return void 0;
    return this.items[this.count - 1];
  }
  isEmpty = () => this.count === this.lowestCount
  size = () => this.count - this.lowestCount
  clear = () => {
    this.count = 0;
    this.lowestCount = 0;
    this.items = {};
  }
  toString = () => {
    if (this.isEmpty()) 
      return '';
    let objString = `${this.items[this.lowestCount]}`;
    for (let i = this.lowestCount + 1; i < this.count; i++) {
      objString = `${objString},${this.items[i]}`;
    }
    return objString;
  }
}

链表

动态数据结构,可以随意添加或移除项,它会按需扩容。有序的元素组合,不同于数组,链表中的元素在内存中不是连续放置的,每个元素由一个存储元素本身的节点和一个指向下一个元素的引用组成

class Node {
	constructor(el) {
		this.element = el
		this.next = undefined
	}
}
function defaultEquals(a,b) {
	return a === b
}

class LinkedList {
	constructor(equalsFn = defaultEquals) {
		this.count = 0
		this.head = undefined
		this.equalsFn = equalsFn
	}
	push = el => {
		const node = new Node(el)
		let current
		if(this.head == null) {
			this.head = node
		} else {
			current = this.head
			while(current.next) {
				current = current.next
			}
			current.next = node
		}
		this.count ++
	}
	remove = el => {}
	indexOf = el => {}
	removeAt = index => {
		if(index >= 0 && index < this.count) {
			let current = this.head
			if (index === 0) {
				this.head = current.next
			} else {
				let previous
				for(let i = 0; i < index; i++) {
					previous = current
					current = current.next
				}
				previous.next = current.next
			}
			this.count--
			return current.element
		} else {
			return undefined
		}
	}
}

二叉搜索树

只允许在左侧节点存储比父节点小的值,在右侧节点存储比父节点大的值

class Node{
	constructor(key) {
		this.key = key
		this.left = null
		this.right = null
	}
}

class BST {
	constructor() {
		this.root = null
	}
	insert (key) {
		if(this.root === null) {
			this.root = new Node(key)
		} else {
			this.insertNode(this.root, key)
		}
	}
	insertNode(node, key) {
		if(node.key > key) {
			if(node.left == null) {
				node.left = new Node(key)
			} else {
				this.insertNode(node.left, key)
			}
		} else {
			if(node.right == null) {
				node.right = new Node(key)
			} else {
				this.insertNode(node.right, key)
			}
		}
	}
	inOrder(cb) {
		this.inOrderNode(this.root, cb)
	}
	inOrderNode(node, cb) {
		if(node !== null) {
			this.inOrderNode(node.left, cb)
			cb(node.key)
			this.inOrderNode(node.right, cb)
		}
	}
	search(key) {
		return this.searchNode(this.root, key)
	}
	min() {
		return this.minNode(this.root)
	}
	minNode(node) {
		if (node.left == null) {
			return node.key
		} else {
			this.minNode(node.left)
		}
	}
	searchNode(node, key) {
		if(node === null) {
			return false 
		}
		if (node.key > key) {
			return this.searchNode(node.left, key)
		} else if (node.key < key) {
			return this.searchNode(node.right, key)
		} else {
			return true 
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值