JavaScript鏈表結構——雙向鏈表

JavaScript鏈表結構——雙向鏈表

//雙向鏈表類
function DoublyLinkList(){
	//節點類
	function Node(data){
		this.data = data
		this.pre = null
		this.next = null
	}
	//初始化屬性
	this.head = null
	this.tail = null
	this.length = 0
	/*
	*
	* 1.append方法,在雙鏈表尾部添加新節點
	* 
	*/
	DoublyLinkList.prototype.append = function(data){
		let node = new Node(data)
		//判斷當前鏈表是否爲空
		if (this.length == 0){
			this.head = node
			this.tail = node
		}
		else{
			node.prev = this.tail
			this.tail.next = node
			this.tail = node
		}
		//鏈表長度+1
		this.length += 1
	}
	/*
	*
	* 2.1 toString方法
	* 
	*/
	DoublyLinkList.prototype.toString = function(){
		return this.backwardString()
	}
	/*
	*
	* 2.2 forwardString方法,從後向前返回字符串形式的數據
	* 
	*/
	DoublyLinkList.prototype.forwardString = function(){
		let listString = ''
		let current = this.tail
		while(current != null){
			listString += current.data + ' '
			current = current.prev
		}
		return listString
	}
	/*
	*
	* 2.3 backwardString方法,從前向後返回字符串形式的數據
	* 
	*/
	DoublyLinkList.prototype.backwardString = function(){
		let listString = ''
		let current = this.head
		while(current != null){
			listString += current.data + ' '
			current = current.next
		}
		return listString
	}
	/*
	*
	* 3. insert方法,指定位置插入節點
	* 
	*/
 DoublyLinkList.prototype.insert = function(data, position){	
	 //判斷position是否越界
	 if (position < 0 || position > this.length){
		 return false
	 }
	 //新建節點對象
	 let node = new Node(data)
	 //1.判斷插入位置是否爲頭部
	 if (position == 0){
		 //1.1判斷當前鏈表是否爲空
		 if (this.length == 0){
			 this.tail = node
		 }
		 //1.2當前鏈表不爲空時
		 else{
			 this.head.prev = node
			 node.next = this.head
		 }
		 //無論當前鏈表是否爲空,head都重新指向新節點
		 this.head = node
	 }
	 //2.判斷插入位置是否爲尾部
	 else if (position == this.length){
		 this.append(data)
	 }
	 //3.插入的位置既不是頭部也不是尾部
	 else{
		 let current = null
		 //3.1 插入的位置離頭部比較近
		 if (position <= this.length/2 - 1){
			 current = this.head
			 let index = 0
			 //找到要插入的位置
			 while (index < position){
				 current = current.next
				 index ++
			 }
		 }
		 //3.2 插入的位置離尾部比較近
		 else {
			 current = this.tail
			 let index = this.length - 1
			 //找到要插入的位置
			 while (index > position){
				 current = current.prev
				 index --
			 }
		 }
		 //改變指針指向
		 node.next = current
		 node.prev = current.prev
		 current.prev.next = node
		 current.prev = node
	 }
	 //鏈表長度+1
	 this.length += 1
 }
 /*
 *
 * 4. get方法,查找指定位置的節點的數據
 * 
 */
 DoublyLinkList.prototype.get = function(position){
	 //越界判斷
	 if (position < 0 || position >= this.length){
		 return null
	 }
	 
	 let current = null
	 //查找的位置離頭部比較近
	 if (position <= this.length/2 -1){
		 current = this.head
		 let index = 0
		 while (index < position){
			 current = current.next
			 index ++
		 }
	 }
	 //查找的位置離尾部比較近
	 else {
		 current = this.tail
		 let index = this.length - 1
		 while (index > position){
			 current = current.prev
			 index --
		 }
	 }
	 return current.data
 }
 /*
 *
 * 5. indexOf方法,通過數據查找對應的索引
 * 
 */ 
 DoublyLinkList.prototype.indexOf = function(data){
	 let current = this.head
	 let index = 0
	 while (current != null){
		 if (current.data == data){
			 //找到返回index
			 return index
		 }
		 current = current.next
		 index ++
	 }
	 //沒找到返回-1
	 return -1
 }
 /*
 *
 * 6. update方法,更新指定位置的節點的數據
 * 
 */ 
  DoublyLinkList.prototype.update = function(newData, position){
		if (position < 0 || position >= this.length){
			return false
		}
		let current = null
		if (position <= this.length/2 -1){
			current = this.head
			let index = 0
			while (index < position){
				current = current.next
				index ++
			}
		}
		else {
			current = this.tail
			let index = this.length - 1
			while (index > position){
				current = current.prev
				index --
			}
		}
		//打印數據變化
		console.log(current.data + '=>' + newData)
		current.data = newData
	}
	/*
	*
	* 7. removeAt方法,移除指定位置的節點
	* 
	*/
	DoublyLinkList.prototype.removeAt = function(position){
		if (position < 0 || position >= this.length){
			return null
		}
		
		let current = this.head
		
		//1. 移除的位置爲頭部
		if (position == 0){
			//1.1 鏈表的長度爲1
			if (this.length == 1){
				this.head = null
				this.tail = null
			}
			//1.2 鏈表的長度不爲1
			else {
				this.head.next.prev = null
				this.head = this.head.next
			}
		}
		//2. 移除的位置爲尾部
		else if (position == this.length -1){
			current = this.tail
			this.tail.prev.next = null
			this.tail = this.tail.prev
		}
		//3. 移除的位置不是頭部或尾部
		else {
			//3.1 從頭部開始尋找
			if (position <= this.length -1){
				current = this.head
				let index = 0
				while (index < position){
					current = current.next 
					index ++
				}
			}
			//3.2 從尾部開始尋找
			else {
				current = this.tail
				let index = this.length -1
				while (index > position){
					current = current.prev 
					index --
				}
			}
			//改變指針指向
			current.prev.next = current.next
			current.next.prev = current.prev
		}
		//鏈表長度-1
		this.length -= 1
		//返回刪除的數據
		return current.data
	}
	/*
	*
	* 8. remove方法,移除指定數據的節點
	* 
	*/ 
	DoublyLinkList.prototype.remove = function(data){
		let index = this.indexOf(data)
		return this.removeAt(index)
	}
	
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章