數據結構JavaScript——單鏈表、循環鏈表

數據結構系列前言:

        數據結構作爲程序員的基本知識,需要我們每個人牢牢掌握。近期我也展開了對數據結構的二次學習,來彌補當年挖的坑。。。。。。   當時上課的時候也就是跟着聽課,沒有親自實現任何一種數據結構,更別提利用數據結構來解決問題了。  現在就來填坑了奮鬥   在這裏提醒看到我博客的孩子們,如果你還是在校生,永遠不要輕視任何一門基礎課的學習,這個時候挖的坑,要麼需要用雙倍的努力去填,要麼會直接影響一個人的能力等等。。。。。。 千萬別給自己挖坑


進入正題,關於鏈表的數據結構知識,這裏簡單介紹下:

        鏈表是一種物理存儲單元上非線性、非連續性的數據結構(它在數據邏輯上是線性的),它的每個節點由兩個域組成:數據域和指針域。數據域中存儲實際數據,指針域則存儲着指針信息,指向鏈表中的下一個元素或者上一個元素。正是由於指針的存在,鏈表的存儲在物理單元是非連續性的。 

        鏈表的優點和缺點同樣明顯。和線性表相比,鏈表在添加和刪除節點上的效率更高,因爲其只需要修改指針信息即可完成操作,而不像線性表(數組)那樣需要移動元素。同樣的,鏈表的長度在理論上也是無限的(在存儲器容量範圍內),並可以動態變化長度,相比線性表優勢很大。 相應的,由於線性表無法隨機訪問節點,只能通過指針順着鏈表進行遍歷查詢來訪問,故其訪問數據元素的效率比較低。  


下面是JS部分

        這裏面封裝了的常用方法及描述:

方法 描述
append(element)   向鏈表尾部添加結點element
insert(position,element)  向位置position處插入結點element
removeAt(position)  按照索引值position刪除結點
remove(element)  搜索並刪除給定結點element
remove()  刪除鏈表中最後一個結點
indexOf(element) 查找並返回給定結點element的索引值
isEmpty()  判斷鏈表是否爲空
size()  獲取鏈表長度
toString()  轉換爲字符串輸出
getHead() 獲取頭結點
getTail()  獲取尾結點

       對於各常用方法的算法描述在這裏就不寫了,相信大家都可以輕易讀懂並理解,畢竟都是非常基礎的知識了。


單鏈表:

function LinkedList(){
	/*節點定義*/
	var Node = function(element){
		this.element = element; //存放節點內容
		this.next = null; //指針
	}

	var length = 0, //存放鏈表長度
	    head = null; //頭指針

	this.append = function(element){
	 	var node = new Node(element), 
	 	    current; //操作所用指針

	 	if (!head){
	 		head = node;
	 	}else {
	 		current = head;

	 		while(current.next){
	 			current = current.next;
	 		}

	 		current.next = node;
	 	}

	 	length++;
	 	return true;
	};

	this.insert = function(position, element){
	 	if (position >= 0 && position <= length) {
	 		var node = new Node(element),
		 		current = head,
		 		previous,
		 		index = 0;

	 		if(position === 0){
	 			node.next = current;
	 			head = node;
	 		}else{
	 			while(index++ < position){
	 				previous = current;
	 				current = current.next;
	 			}
	 			node.next = current;
	 			previous.next = node;
	 		}

	 		length++;
	 		return true;
	 	}else{
	 		return false;
	 	}
	 };

	this.removeAt = function(position){
	 	if(position > -1 && position < length){
	 		var current = head,
	 		    previous,
	 		    index = 0;

	 		if (position === 0) {

	 			head = current.next;

	 		}else{

	 			while (index++ < position){
	 				previous = current;
	 				current = current.next;
	 			}

	 			previous.next = current.next;
	 		};

	 		length--;
	 		return current.element;
	 	}else{
	 		return null;
	 	}
	};

	this.remove = function(element){
	 	var current = head,
	 	    previous;

	 	if(element === current.element){
	 		head = current.next;
	 		length--;
	 		return true;
	 	}
	 	previous = current;
	 	current = current.next;

	 	while(current){
	 		if(element === current.element){
	 			previous.next = current.next;
	 			length--;
	 			return true;
	 		}else{
	 			previous = current;
	 			current = current.next;
	 		}
	 	}
	 	return false;
	};

	this.remove = function(){
	 	if(length < 1){
	 		return false;
	 	}

	 	var current = head,
 		previous;

	 	if(length == 1){
	 		head = null;
	 		length--;
	 		return current.element;
	 	}

 	
	 	while(current.next !== null){
	 		previous = current;
	 		current = current.next;
	 	}

	 	previous.next = null;
	 	length--;
	 	return current.element;
	};

	this.indexOf = function(element){
	 	var current = head,
	 	    index = 0;

	 	while(current){
	 		if(element === current.element){
	 			return index;
	 		}
	 		index++;
	 		current = current.next;
	 	}

	 	return false;
	};

	this.isEmpty = function(){
	 	return length === 0;
	};

	this.size = function(){
	 	return length;
	};

	this.toString = function(){
	 	var current = head,
	 	    string = '';

	 	while(current){
	 		string += current.element;
	 		current = current.next;
	 	}
	 	return string;
	};	 

	this.getHead = function(){
	 	return head;
	}
	
}

循環鏈表:在單鏈表的基礎上,將尾節點的指針指向頭結點,就構成了一個循環鏈表。環形鏈表從任意一個節點開始,都可以遍歷整個鏈表。

function CircularLinkedList(){
	var Node = function(element){
		this.element = element;
		this.next = null;
	}

	var length = 0,
	    head   = null;

	this.append = function(element){
		var node = new Node(element),
		    current;

		if (!head) {
			head = node;
			node.next = head;
		}else{
			current = head;

			while(current.next !== head){
				current = current.next;
			}

			current.next = node;
			node.next = head;
		};

		length++;
		return true;
	};

	this.insert = function(position, element){
		if(position > -1 && position < length){
			var node = new Node(element),
			    index = 0,
			    current = head,
			    previous;


			if (position === 0) {

				node.next = head;
				head = node;

			}else{

				while(index++ < position){
					previous = current;
					current = current.next;
				}

				previous.next = node;
				node.next = current;

			};

			length++;
			return true;
		}else{
			return false;
		}
	};

	this.removeAt = function(position){
		if(position > -1 && position < length){
	 		var current = head,
	 		    previous,
	 		    index = 0;

	 		if (position === 0) {

	 			head = current.next;

	 		}else{

	 			while (index++ < position){
	 				previous = current;
	 				current = current.next;
	 			}

	 			previous.next = current.next;
	 		};

	 		length--;
	 		return current.element;
	 	}else{
	 		return null;
	 	}
	};

	this.remove = function (element){
		var current = head,
		    previous,
		    indexCheck = 0;

		while(current && indexCheck < length){
			if(current.element === element){
				if(indexCheck == 0){
					head = current.next;
					length--;
					return true;
				}else{
					previous.next = current.next;
					length--;
					return true;
				}
			}else{
				previous = current;
				current = current.next;
				indexCheck++;
			}
		}
		return false;
	};

	this.remove = function(){
		if(length === 0){
			return false;
		}

		var current = head,
		    previous,
		    indexCheck = 0;

		if(length === 1){
			head = null;
			length--;
			return current.element;
		}

		while(indexCheck++ < length){
			previous = current;
			current = current.next;
		}
		previous.next = head;
		length--;
		return current.element;
	};

	this.indexOf = function(element){
		var current = head,
		    index = 0;

		while(current && index < length){
			if(current.element === element){
				return index;
			}else{
				index++;
				current = current.next;
			}
		}
		return false;
	};


	this.isEmpty = function(){
	 	return length === 0;
	};

	this.size = function(){
	 	return length;
	};

	this.toString = function(){
	 	var current = head,
	 	    string = '',
	 	    indexCheck = 0;

	 	while(current && indexCheck < length){
	 		string += current.element;
	 		current = current.next;
	 		indexCheck++;
	 	}

	 	return string;
	};	 

}

使用方法:

        

在類外部擴充方法:

  

關於雙向鏈表與雙向循環鏈表,見本人另一篇博客:  雙向鏈表、雙向循環鏈表的JS實現

對於鏈表的封裝,完整版地址:https://github.com/zhuwq585/Data-Structure-in-JavaScript/blob/master/LinkedList.js

發佈了29 篇原創文章 · 獲贊 30 · 訪問量 2萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章