棧是一種聽從後進先出原則的有序集合。新添加的或待刪除的元素都保存在棧的末尾,稱做棧頂,另外一端叫作棧底。在棧裏,新元素都靠近棧頂,舊元素都接近棧底。node
class Stack{
constructor(){
this.item = []
}
push(element){
this.item.push(element)
}
pop(){
return this.item.pop()
}
peek(){
return this.item[this.item.length-1]
}
isEmpty(){
return this.item.length === 0
}
size(){
return this.item.length
}
clear(){
this.item = []
}
print(){
console.log(item.toString())
}
}
複製代碼
隊列是一種遵循先進先出原則的一組有序的項。隊列在尾部添加元素,並從頂部移除元素。最新添加的元素必須排在隊列的末尾。數組
class Queue{
constructor(){
this.item = []
}
enqueue(element){
this.item.push(element)
}
dequeue(){
return this.item.shift()
}
front(){
return this.item[0]
}
isEmpty(){
return this.item.length === 0
}
clear(){
this.items = []
}
size(){
return this.item.length
}
}
複製代碼
鏈表儲存有序的元素集合,但不一樣於數組,鏈表的每一個元素由一個儲存元素自己的節點和一個指向下一個元素的引用組成。bash
節點只有鏈向下一個節點的連接。 數據結構
class Node{
constructor(element){
this.element = element
this.next = null
}
}
class LinkedList{
constructor(){
this.length = 0
this.head = null
}
/********末尾插入元素********/
append(element){
let node = new Node(element),current
if(this.head === null){
this.head = node
}else{
current = this.head
while(current.next){
current = current.next
}
current.next = node
}
this.length++
}
/********指定位置插入元素********/
insert(position, element){
if(position>=0 && position<this.length){
let node = new Node(element)
let current = this.head
let previous
let index = 0
if(position ===0 ){
current.next = current
current = node
}else{
while(index++ < position){
previous = current
current = current.next
}
node.next = current
previous.next = node
}
length++
return true
}else{
return false
}
}
/********指定位置刪除元素********/
removeAt(position){
if(position>=0 && position<this.length){
let current = this.head
let previous
let index = 0
if(position ===0 ){
this.head = current.next
}else{
while(index++ < position){
previous = current
current = current.next
}
previous.next = current.next
}
length--
return current.element
}else{
return null
}
}
/********指定值刪除元素********/
remove(element){
let index = this.indexOf(element)
return this.removeAt(index)
}
/********將鏈表轉換成一個字符串********/
toString(){
let current = this.head
let string = ""
while(current){
string += current.element + (current.next ? ">" : "")
current = current.next
}
return string
}
/********在鏈表中查找元素的位置********/
indexOf(element){
let current = this.head
index = 0
while(current){
if(element === current.element){
return index
}
index++
current = current.next
}
return -1
}
isEmpty(){
return this.length === 0
}
size(){
return this.length
}
getHead(){
return this.head
}
}
複製代碼
節點的連接是雙向的,一個鏈向下一個元素,另外一個鏈向前一個元素。 app
class Node{
constructor(element){
this.element = element
this.next = null
this.prev = null
}
}
class DoublyLinkedList{
constructor(){
this.length = 0
this.head = null
this.tail = null
}
insert(position, element){
if(position>=0 && position<this.length){
let node = new Node(element)
let current = this.head
let previous
let index = 0
if(position === 0){
if(!this.head){
this.head = node
this.tail = node
}else{
node.next = current
current.prev = node
this.head = node
}
}else if(position === this.length){
current = this.tail
current.next = node
node.prev = current
tail = node
}else{
while(index++ < position){
previous = current
current = current.next
}
node.next = current
previous.next = node
current.prev = node
node.prev = previous
}
length++
return true
}else{
return false
}
}
removeAt(position){
if(position>=0 && position<this.length){
let current = this.head
let previous
let index = 0
if(position ===0 ){
this.head = current.next
if(this.length === 1){
tail = null
}else{
head.prev = null
}
}else if(position === this.length-1){
current = tail
tail = current.prev
tail.next = null
}else{
while(index++ < position){
previous = current
current = current.next
}
previous.next = current.next
current.next.prev = previous
}
length--
return current.element
}else{
return null
}
}
}
複製代碼
最後一個元素指向下一個元素的指針不是引用null,而是指向第一個元素head。 ui
有指向head元素的tail.next,和指向tail元素的head.prev。 this
無序且惟一的項,以值-值形式儲存元素。spa
class Set{
constructor(){
this.items = {}
}
has(value){
return value in this.items
}
add(value){
if(!this.has(value)){
this.items[value]=value
return true
}
else{
return false
}
}
remove(){
if(this.has(value)){
delete this.items[value]
return true
}
else{
return false
}
}
clear(){
this.items = {}
}
size(){
return Object.keys(this.items).length
}
values(){
let values = []
for(let i=0,keys=Object.keys(this.items); i<keys.length; i++){
values.push(this.items[keys[i]])
}
return values
}
}
複製代碼
以鍵-值形式儲存元素,以遍歷整個數據結構的方式獲取值。指針
class Dictionary{
constructor(){
this.items = {}
}
has(key){
return key in this.items
}
set(key, value){
item[key] = value
}
delete(key){
if(this.has(key)){
delete this.items[key]
return true
}
else{
return false
}
}
get(key){
return this.has[key] ? items[key] : undefined
}
values(){
let values = []
for(var k in items){
if(this.has(k)){
values.push(items[key])
}
}
return values
}
keys(){
return Object.keys(items)
}
getItems(){
return items
}
clear(){
this.items = {}
}
size(){
return Object.keys(this.items).length
}
}
複製代碼
以鍵-值形式儲存元素,可以知道值的具體位置,所以可以快速檢索到該值。code
衝突版:將 key 的每一個字符的 Unicode 碼值的和加到 hash 變量中,hash會有衝突。
class HashTable{
constructor(){
this.table = []
}
loseloseHashCode(key){
let hash = 0
for(let i = 0; i<key.length; i++){
hash += key.charCodeAt(i)
}
return hash % 37
}
put(key, value){
let position = this.loseloseHashCode(key)
console.log(position + ":" + key)
table[position] = value
}
get(key){
return table[loseloseHashCode(key)]
}
remove(key){
table[loseloseHashCode(key)] = undefined
}
}
複製代碼
解決衝突版:分離連接,爲散列表的每個位置建立一個鏈表並將元素存儲在裏面。
class valuePair{
constructor(key, value){
this.key = key
this.value = value
}
toString(){
return `[${this.key} - ${this.value}]`
}
}
class HashTable{
constructor(){
this.table = []
}
loseloseHashCode(key){
let hash = 0
for(let i = 0; i<key.length; i++){
hash += key.charCodeAt(i)
}
return hash % 37
}
put(key, value){
let position = this.loseloseHashCode(key)
if(table[position] === undefined){
table[position] = new LinkedList()
}
table[position].append(new ValuePair(key, value))
}
get(key){
return table[loseloseHashCode(key)]
}
remove(key){
table[loseloseHashCode(key)] = undefined
}
}
複製代碼