javascript-链表

链表

链表:
链表实际上是线性表的链式存储结构,与数组不同的是,它是用一组任意的存储单元来存储线性表中的数据,存储单元不一定是连续的,
且链表的长度不是固定的,链表数据的这一特点使其可以非常的方便地实现节点的插入和删除操作
链表的每个元素称为一个节点,每个节点都可以存储在内存中的不同的位置,为了表示每个元素与后继元素的逻辑关系,以便构成“一个节点链着一个节点”的链式存储结构。
在这里插入图片描述

			let LinkNode=function(val){
				this.val=val;
				this.next=null;
			}
			//链表
			function LinkList(){
				
				this.length=0;
				this.head=null;
			}
			//增加节点
			LinkList.prototype.append=function(val){
				let node=new LinkNode(val)
				if(this.head==null) {
					this.head=node
					}
				else{
					let current=this.head;
					//找到最后一个节点
					while(current.next!=null){
						current=current.next;
					}
					current.next=node;
				}
				this.length++;
				
			}
			
			//查找到指定位置节点
			LinkList.prototype.getNodeAt=function(index){
				if(index<0||index>this.length-1) return null;
				let current=this.head;
				while(index>0){
					current=current.next;
					index--;
				}
				return current;
			}
			
			//查找指定元素所在节点索引
			LinkList.prototype.IndexOf=function(val){
				let count=0
				let current=this.head;
				while(count<this.length){
					if(current.val==val) return count;
					current=current.next;
					count++;
				}
				return -1;
			}
			//在指定位置插入节点
			LinkList.prototype.insert=function(position,val){
				if(position<0||position>this.length-1) return false;
				let node=new LinkNode(val);
				if(position==0){
					node.next=this.head;
					this.head=node;
				}else{
					let pre=this.getNodeAt(position-1);
					node.next=pre.next;
					pre.next=node;
				}
				this.length++;
				return true;
				
			}
			//删除指定位置节点
			LinkList.prototype.removeAt=function(position){
			     if(position<0||position>this.length-1) return false;
				 
				 if(position==0){
					 this.head=this.head.next;
				 }else{
					 let pre=this.getNodeAt(position-1);
					 pre.next=pre.next.next
				 }
				 this.length--;
				 return true;
			}
			
			//打印
			LinkList.prototype.toString=function(){
				
				let res=''
				let current=this.head
				let size=this.length;
				while(size>0){
					let nextValue=current.next?current.next.val:null
					res+=`{Nodevalue:${current.val} next:${nextValue } }`
					size--;
					current=current.next;
				}
				
				return res
			}
			//翻转链表
			LinkList.prototype.reverse=function(){
				if(this.head==null) return null;
				let p=this.head;
				let q=null;
				while(p.next!==null){
					q=p.next;
					p.next=q.next;
					q.next=this.head
					this.head=q
				
				}
				return this.head
			}
			
			/*判断有没有环,环的入口点,环的长度
			1、设置快慢指针,当快指针第一次和慢指针相遇时,可以判断有环
		    2、为了求入口点,可以在相遇时再设置一个指向头结点的指针,让
			慢指针和新的指针一起走,相遇点就是环入口点
			3、环长度可以让快慢指针相遇后,再次出发,第二次相遇时慢指针
			走过的步数就是环长度
			*/
		   //判断环
		    LinkList.prototype.hasCycle=function(){
				let slow=this.head;
				let fast=this.head;
				while(fast.next!=null&&fast!=null){
					slow=slow.next;
					fast=fast.next.next;
					if(fast==slow) return true;
				}
				return false
			}
			//判断入口点
			LinkList.prototype.cycleEnter=function(){
				let slow=this.head;
				let fast=this.head;
				while(fast.next!=null&&fast!=null){
					slow=slow.next;
					fast=fast.next.next;
					if(fast==slow) break;
				}
				if(fast.next==null||fast==null) return null;
				
				fast=this.head;
				while(fast!=slow){
					fast=fast.next;
					slow=slow.next;
				}
				return fast;
			}
			//判断环长度
			LinkList.prototype.cycleLength=function(){
				let slow=this.head;
				let fast=this.head;
				let size=1;
				while(fast.next!=null&&fast!=null){
					slow=slow.next;
					fast=fast.next.next;
					if(fast==slow) break;
				}
				if(fast.next==null||fast==null) return 0;
				fast=fast.next.next;
				slow=slow.next;
				while(slow!=fast){
                   size++;
					fast=fast.next.next;
					slow=slow.next;
				}
				
				return size;
			}
			 var list=new LinkList()
			 list.append('1')
			 list.append('2')
			 list.append('3')
			 list.append('4')
			 console.log(list)
			console.log(list.getNodeAt(2))
			console.log(list.IndexOf('4'))
			 list.insert(0,'0')
			 console.log(list.toString())
			 list.reverse();
			 console.log(list.toString())
			 
			 //构建有环链表
			var list2=new LinkList()
			list2.append('1')
			list2.append('2')
			list2.append('3')
			list2.append('4')
			list2.getNodeAt(list2.length-1).next=list2.getNodeAt(1)
			console.log(list2.toString())
			console.log(list2.hasCycle())
			console.log(list2.cycleEnter())
			console.log(list2.cycleLength())

结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值