读【数据结构与算法】之链表

链表是由一组节点组成的集合。每一个节点都使用一个对象的引用指向他的下一个节点,指向另一个节点的引用就叫链。这样也就形成了链表。

实现链表需要两个类,一个是节点类Node,还有链表LinkedList类。

基本链表

最基本链表,也就是从头节点开始,一个链接着一个节点,直至最后一个,遍历的话只能从头开始到尾。

基本实现:

/**
 * Class Node
 * 节点类
 */

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


/**
 * Class LinkedList
 * 链表 LinkedList
 */

function LinkedList() {
	this.head = new Node('head');
}

LinkedList.prototype = {

	constructor: LinkedList,

	/**
	 * 查找链表项
	 * @param  {Any} item  某项
	 * @return {Node|Null} 节点或者null
	 */
	find: function find(item) {
		var currNode = this.head;
		while (currNode && currNode.element !== item) {
			currNode = currNode.next;
		}
		return currNode;
	},

	/**
	 * 查找链表中哪个节点的下一个节点中的元素是查找项
	 * @param  {Any} item  查找项
	 * @return {Node|Null} 节点或者null
	 */
	findPrevious: function findPrevious(item) {
		var currNode = this.head;
		while (currNode.next != null && currNode.next.element !== item) {
			currNode = currNode.next;
		}
		return currNode;
	},

	/**
	 * 在某项后插入新项
	 * @param  {Any} newElement 插入新项
	 * @param  {Any} item       某项
	 * @return {Undefined} undefined
	 */
	insert: function insert(newElement, item) {
		var current = this.find(item);
		if (!current) return;
		var newNode = new Node(newElement);
		newNode.next = current.next;
		current.next = newNode;
	},

	/**
	 * 得到所有项
	 * @return {Array} 所有项
	 */
	display: function display() {
		var ret = [];
		var currNode = this.head;
		while (currNode.next != null) {
			ret.push(currNode.next.element);
			currNode = currNode.next;
		}
		return ret;
	},

	/**
	 * 移除链表中某项
	 * @param  {Any} item  某项
	 * @return {Undefined} undefined
	 */
	remove: function remove(item) {
		var preNode = this.findPrevious(item);
		if (preNode && preNode.next != null) {
			preNode.next = preNode.next.next;
		}
	}

};

双向链表

对于基本链表,如果想要从尾往头去遍历的话,就很困难了。那么咱们可以给Node增加一个属性,通过该属性执行前一个节点的引用,这样,也就形成了双向链表。对于双向链表,每一个节点都能找到他的前一个和后一个节点。

基本实现:

/**
 * Class BidNode
 * 双向节点类
 */

function BidNode(element) {
	this.element = element;
	this.next = null;
	this.previous = null;
}


/**
 * Class BidLinkedList
 * 双向链表 BidLinkedList
 */

function BidLinkedList() {
	this.head = new BidNode('head');
}

BidLinkedList.prototype = {

	constructor: BidLinkedList,

	/**
	 * 查找链表项
	 * @param  {Any} item  某项
	 * @return {BidNode|Null} 节点或者null
	 */
	find: function find(item) {
		var currNode = this.head;
		while (currNode && currNode.element !== item) {
			currNode = currNode.next;
		}
		return currNode;
	},

	/**
	 * 查找链表中最后的节点
	 * @return {BidNode|Null} 节点或者null
	 */
	findLast: function findLast() {
		var currNode = this.head;
		while (currNode.next != null) {
			currNode = currNode.next;
		}
		return currNode;
	},

	/**
	 * 在某项后插入新项
	 * @param  {Any} newElement 插入新项
	 * @param  {Any} item       某项
	 * @return {Undefined} undefined
	 */
	insert: function insert(newElement, item) {
		var current = this.find(item);
		if (!current) return;
		var newNode = new BidNode(newElement);
		newNode.next = current.next;
		newNode.previous = current;
		current.next = newNode;
	},

	/**
	 * 得到所有项
	 * @return {Array} 所有项
	 */
	display: function display() {
		var ret = [];
		var currNode = this.head;
		while (currNode.next != null) {
			ret.push(currNode.next.element);
			currNode = currNode.next;
		}
		return ret;
	},

	/**
	 * 反向得到所有项
	 * @return {Array} 所有项
	 */
	disReverse: function disReverse() {
		var ret = [];
		var currNode = this.findLast();
		while (currNode.previous != null) {
			ret.push(currNode.element);
			currNode = currNode.previous;
		}
		return ret;
	},

	/**
	 * 移除链表中某项
	 * @param  {Any} item  某项
	 * @return {Undefined} undefined
	 */
	remove: function remove(item) {
		var currNode = this.find(item);
		if (currNode && currNode.next != null) {
			currNode.previous.next = currNode.next;
			currNode.next.previous = currNode.previous;
			currNode.next = null;
			currNode.previous = null;
		}
	}

};

具体运行例子请看demojs实现链表

发布于: 2014年 09月 05日