循环链表可以像链表一样只有单向引用,也可以像双向链表一样有双向引用。循环链表和链表之间唯一的区别在于,最后一个元素指向下一个元素的指针(tail.next)不是引用null,而是指向第一个元素(head)
双向循环链表有指向head元素的tail.next,和指向tail元素的head.prev
实现一个循环链表
function CircularLinkedList() {let Node = function(element){this.element = element;this.next = null;};let length = 0;let head = null;this.append = function(element){let node = new Node(element),current;if (head === null){ //first node on listhead = node;} else {current = head;//loop the list until find last itemwhile(current.next !== head){ //last element will be head instead of NULLcurrent = current.next;}//get last item and assign next to added item to make the linkcurrent.next = node;}//set node.next to head - to have circular listnode.next = head;length++; //update size of list};this.insert = function(position, element){//check for out-of-bounds valuesif (position >= 0 && position <= length){let node = new Node(element),current = head,previous,index = 0;if (position === 0){ //add on first positionif(!head){ // if no node in listhead = node;node.next = head;}else{node.next = current;//update last elementwhile(current.next !== head){ //last element will be head instead of NULLcurrent = current.next;}head = node;current.next = head;}} else {while (index++ < position){previous = current;current = current.next;}node.next = current;previous.next = node;}length++; //update size of listreturn true;} else {return false;}};this.removeAt = function(position){//check for out-of-bounds valuesif (position > -1 && position < length){let current = head,previous,index = 0;//removing first itemif (position === 0){while(current.next !== head){ //needs to update last element firstcurrent = current.next;}head = head.next;current.next = head;} else { //no need to update last element for circular listwhile (index++ < position){previous = current;current = current.next;}//link previous with current's next - skip it to removeprevious.next = current.next;}length--;return current.element;} else {return null;}};this.remove = function(element){let index = this.indexOf(element);return this.removeAt(index);};this.indexOf = function(element){let current = head,index = -1;//check first itemif (element == current.element){return 0;}index++;//check in the middle of the listwhile(current.next !== head){if (element == current.element){return index;}current = current.next;index++;}//check last itemif (element == current.element){return index;}return -1;};this.isEmpty = function() {return length === 0;};this.size = function() {return length;};this.getHead = function(){return head;};this.toString = function(){let current = head,s = current.element;while(current.next !== head){current = current.next;s += ', ' + current.element;}return s.toString();};this.print = function(){console.log(this.toString());};}
