栈
栈是一种特殊的列表,栈内的元素只能通过列表的一端访问,这一端称为栈顶。咖啡厅内的一摞盘子是现实世界中常见的栈的例子。只能从最上面取盘子,盘子洗净后,也只能摞在这一摞盘子的最上面。栈被称为一种后入先出(LIFO, last-in-first-out)的数据结构。
- 入栈(push)
- 出栈(pop)
- 查看栈顶元素(peek)
- 获取栈的长度(length)
- 清空栈(clear)
- 判断栈是否空(isEmpty)
栈的应用场景:
- 递归函数的使用。
下面代码实现的栈的构造函数,已经对构造函数的测试验证。
class Stack{
constructor(){
this.data = [];
}
push(el){
this.data.push(el);
}
pop(){
return this.data.pop();
}
peek(){
return this.data[this.data.length-1];
}
length(){
return this.data.length;
}
clear(){
this.data.length = 0;
}
isEmpty(){
return this.data.length == 0 ? true : false
}
}
let s = new Stack();
s.push("张三");
s.push("李四");
s.push("王五");
console.log(s.length()); //3
console.log(s.pop()); //"王五"
console.log(s.length()); //2
console.log(s.peek()); //"李四"
console.log(s.length()); //2
s.clear();
console.log(s.length()); //0
console.log(s.isEmpty()); //true
队列
队列是一种列表,不同的是队列只能在队尾插入元素,在队首删除元素。队列用于存储按顺序排列的数据,先进先出,这点和栈不一样,在栈中,最后入栈的元素反而被优先处理。可以将队列想象成在银行前排队的人群,排在最前面的人第一个办理业务,新来的人只能在后面排队,直到轮到他们为止。 队列是一种先进先出(First-In-First-Out, FIFO)的数据结构。
- 入队(push)
- 出队(pop)
- 查看对头元素(peek)
- 获取队列的长度(length)
- 清空队列(clear)
- 判断队列是否空(isEmpty)
下面代码实现的队列的构造函数,已经对构造函数的测试验证。
class Queue{
constructor(){
this.data = [];
}
push(el){
this.data.push(el);
}
pop(){
return this.data.shift();
}
peek(){
return this.data[0];
}
length(){
return this.data.length;
}
clear(){
this.data.length = 0;
}
isEmpty(){
return this.data.length == 0 ? true : false
}
}
let q = new Queue();
q.push("张三");
q.push("李四");
q.push("王五");
console.log(q.length()); //3
console.log(q.pop()); //"张三"
console.log(q.length()); //2
console.log(q.peek()); //"李四"
console.log(q.length()); //2
q.clear();
console.log(q.length()); //0
console.log(q.isEmpty()); //true
链表
链表是由一组节点组成的集合。每个节点都使用一个对象的引用指向它的后继。指向另一个节点的引用叫做链。在链表最最前面有一个特殊的节点,叫做头节点,链表的尾元素指向一个null节点。遍历链表,就是跟着链接,从链表的首元素一直走到尾元素(不包含链表的头节点,头节点通常只是用来作为链表的接入点)。
- 向链表插入元素(insert)
- 从链表中删除元素(remove)
- 输出链表(toString)
下面代码实现的队列的构造函数,已经对构造函数的测试验证。
class Node{
constructor(el){
this.el = el;
this.next = null;
}
}
class linkedList{
constructor(){
this.head = new Node("head");
}
//查找链表中指定元素
find(item){
let currNode = this.head;
while(currNode != null && currNode.el != item){
currNode = currNode.next;
}
return currNode;
}
//查找指定元素的前驱节点
findPrevious(item){
let currNode = this.head;
while(currNode.next != null && currNode.next.el != item){
currNode = currNode.next;
}
return currNode;
}
insert(newEl,item){
let newNode = new Node(newEl);
let current = this.find(item);
//元素不存在,返回false
if( current == null ) return false;
newNode.next = current.next;
current.next = newNode;
return true;
}
remove(item){
let prevNode = this.findPrevious(item);
//元素不存在,返回false
if(prevNode.next == null) return false;
prevNode.next = prevNode.next.next;
return true;
}
toString(){
let currNode = this.head;
let str = ''
while(currNode.next != null){
str = str + currNode.next.el + ' -> ';
currNode = currNode.next;
}
return str.slice(0,str.length-4);
}
}
let link = new linkedList();
link.insert("张三","head");
link.insert("李四","张三");
link.insert("王五","李四");
link.insert("赵六","王五");
console.log(link.toString()); //张三 -> 李四 -> 王五 -> 赵六
link.remove("王五");
console.log(link.toString()); //张三 -> 李四 -> 赵六