目录
前言
我们在今后的编程学习中,随着知识的不断深入,将会了解到能存储数据的不仅仅有数组,还有链表,本文将基于链表和数组的一些优缺点的对比来介绍链表的基本原理。
一、链表的基本概念
1.1链表的基本组成
链表的元素以一段不连续的存储空间,且每个元素的组成为存储在每个元素本身上的数据以及下一个元素的引用
1.2链表相比于数组的一些优点
在创建链表时不需要从开始就确定大小,并且大小可以无限的延申下去
数组需要扩容时非常麻烦,在中间插入元素时也非常麻烦,链表相比于数组,恰恰可以解决这些问题
链表的存储结构内存空间不一定是连续的,在插入或者删除操作是,除目标节点上一个或者下一个节点以外的节点无关一次时间复杂度为o(1),此操作效率非常高
1.3相对于数组链表的一些缺点
当链表需要得到特定元素时,不能像数组一样根据索引直接访问到目标元素,从头挨个访问
二、代码实现(封装一个完整的链表)
2.1.封装一个基本链表
代码解析,通过封装一个优先级队列我们了解到,使用内部类的方法来定义节点
function linkedList() {
function Node(date){
//内部类
this.date=date;
this.next=next;
}
//属性值
this.head=null;
this.length=0;
}
2.2追加方法
1.append方法向链表尾部追加方法原理:必须先判断链表是否为空
2.如果不是先设置一个curry目标节点,通过next找到最后一个节点即curent.next为空
3.温馨提示:别忘了给链表长度+1
4.图例
5.代码实现
linkedList.prototype.append =function(date ){
var newNode =new Node(date)
// 2.判断是否添加的是第一个节点
if(this.length==0){
this.head=newNode;
}else{
//找到最后一个节点
var curent=this.head;//
while(curent.next!=null){
curent=curent.next;
}
curent.next=newNode
}
}
2.3tostring方法
1.思想和apend方法大同小异,在这里我直接写代码
linkedList.prototype.toString=function(){
var current=this.head;
var listString='';
while(current.next!=null){
listString +=current.date+'';
current=current.next;
}
}
2.4insert方法(在任意位置插入方法)
1.分三种情况:该链表为空,直接再后面插入元素
2.不为空,在链表尾部插入元素,上例实现过,这里不深究
3.不为空且在链表中间插入元素
linkedList.prototype.insert=function(position,date){
var newNode=new newNode(date);
// 进行越界判断
if(position<0||position>=this.length){return null;}
//第一步判断插入的位置position
if(position==0){
//此时当前元素直接插在头节点的后面,将原来插在头节点后面的元素插在当前元素的后面
//然后将当前节点设置为头节点的下一个元素
newNode.next=this.head;
}else{
//通过设置指针找到当前元素要插入的位置
var index=0;
//当前链表从第一个元素节点开始查找,
var current=this.head;
//将当前元素的前一个元素提取出来
var preios=null;
//未找到位置之前指针后移一次
while(index++<position)
preios=current
current=current.next;
}
//找到当前元素
newNode.next=current;
preious.next=newNode;
}
2.5获取指定元素(get方法)
思路:通过控制curry来获取到目标节点
获取到position=1的元素
linkedList.prototype.get=function(position){
if(position<0||position>=this.length){return null}
//通过设置指针来获取相应的data
var current =this.head;
var index=0;
//position=2
while(index++<position){
current=current.next;
}
return current.date
}
2.6返回元素在列表中的索引(indexof方法)
思路通过控制curry来获取到索引
linkedList,prototype.indexOf=function(date){
//设置指针
var current=this.head;
var index=0;
//2.开始查找
while(current){
if(current.date==date){
return index;
}current=current.next;
index+=1;
}
//如果没有找到
return -1;
}
2.7修改目标元素值
思路控制curry来获取到目标元素位置,并修改其值
linkedList,prototype.update=function(position ,newData){
//越界判断
if(position<0||position>=this.length){return null}
//通过设置指针来获取相应的data
var current =this.head;
var index=0;
while(index++<position){
current=current.next;
}
// 3.将position位置node的data修改为newData
current.date=newData
}
2.7移除特定位置中的元素(removeAt)
思路:1.进行越界判断2.判断将要移除的位置是否为第一个元素或者最后一个元素或为中间元素
3.根据2来进行特定操作
//删除指定值
linkedList.prototype.removeAt=function(position){
if(position<0||position>=this.length){return null}
var curry=this.head
if(position==0){
this.head=this.head.next
}
else{
var index=0
var pev=null;
while(index++<position){
pev=curent
curry=curry.next
}
pev.next=curry.next
}
this.length-=1
return curry.date
}
2.8根据data删除元素
思路:先通过indexOf方法获取到position,然后调用removeAt方法删除
linkedList.prototype.remove=function(data){
//获取位置
var position=this.indexOf(data);
return this.removeAt(position)
}
总结:以上就是完整实现一个链表