链表定义
链表是一组节点组成的集合。
链表图示
单向链表定义
链表中的元素,包含元素的值以及指向列表中下一个节点项的指
单向链表的特点
- 用一组任意的内存空间去存储数据元素(空间可以是连续的,也可以不连续)
- 每个节点(node)都由数据本身和一个指向后续节点的指针组成
- 整个链表的存取必须从头指针开始,头指针指向第一个节点
- 最后一个节点的指针指向空null
创建链表
function LinkedList(){
let length=0;
var head=null;
function Node(element){
this.element=element;//当前节点的元素
this.next=null;//下一个节点指针
}
}
Node类表示链表的项
element 用来保存节点上的数据,next 用来保存指向下一个节点的链接
创建单向链表还需要存储第一个节点的引用,可以将引用存在在head的变量中。
链表常见方法
append(element)
//在链表尾部添加新的节点insert(position,element)
//在链表的特定位置插入一个新的节点remove(element)
//在链表中删除节点indexOf(element)
//返回节点在链表中的所有,找不到返回-1removeAt(position)
//在链表特定位置删除该节点isEmpty()
//如果链表为空,返回truesize()
//返回链表包含节点个数toString()
//返回字符串
常见方法实现
toString方法实现,输入单向所有element
this.toString=function(){
let current=head,str=''
while(current){
str+=','+current.element
current=current.next
}
return str.slice(1)
}
向链表尾部添加1个节点,最后链表长度+1
思路梳理:
情况1》当链表为空时。head=null
情况2》当链表不为空时。current.next=null
新增的节点的next==null 实现
实现代码
// 添加元素
this.append=function(element){
// 创建新的节点
var node=new Node(element);
var current;
// 判断是否为空
if(head===null){
head=node;
}else{
// 循环链表直到找到最后一个
current=head
while(current.next){
current=current.next
}
// 将next赋给node
current.next=node
}
length++
}
测试代码
let linkList=new LinkedList()
linkList.append(15)
linkList.append(2)
console.log(linkList.toString())//15,2
在链表中移除节点:从特定位置移除节点
思路梳理:
情况1》移除第1个节点
情况2》移除除第1个以外的节点
实现代码
this.removeAt=function(position){
//检测是否越界
if(position<0||position>length){
return null
}
//正常范围内
let current=head
let previous=null//前一个节点
let index=0
if(position===0){
// 移除第1个元素
head=current.next// 将当前指向下一个的指针为头指针
}else{
while(index++<position){
// 查找需要删除的节点
previous=current
current=current.next
}
//跳转当前元素,将上一个节点与下一个节点相连接
previous.next=current.next
}
length--
return current.element
}
测试代码
let linkList=new LinkedList()
linkList.append(15)
linkList.append(2)
linkList.append(22)
console.log(linkList.removeAt(2))//22
console.log(linkList.toString())//15,2
在任意位置插入1个节点
思路梳理:
情况1:在第一个位置插入新节点
情况2:在中间或者尾部插入新节点
实现代码
this.insert=function(position,element){
//检测越界
if(position<0||position>length+1){
return false
}
let node=new Node(element)
let current=head
let previous=null
let 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
}
测试代码
let linkList=new LinkedList()
linkList.append(15)
linkList.append(2)
linkList.append(22)
console.log(linkList.insert(3,99))//true
console.log(linkList.toString())//15,2,22,99
== 查找单向链表中的节点元素(indexOf)==
this.indexOf=function(element){
let current=head
let index=0
while(current){
if(element===current.element){
return index//返回索引下标
}
index++
current=current.next
}
return -1
}
测试代码
let linkList=new LinkedList()
linkList.append(15)
linkList.append(2)
linkList.append(22)
console.log(linkList.indexOf(22))//2
console.log(linkList.toString())//15,2,22
判断链表是否为空isEmpty
this.isEmpty=function(){
if(length===0){
return true
}else{
return false
}
}
获取链表长度size
this.size=function(){
return length
}
获取头节点
this.getHead=function(){
return head
}
测试代码
let linkList=new LinkedList()
linkList.append(15)
linkList.append(2)
linkList.append(22)
linkList.append(29)
console.log(linkList.getHead())