练习:
合并两条有序链表为一条有序链表:
list1:1 4 6 7
list2: 2 5 8 9
newlist:1 2 4 5 6 7 8 9
代码:
<!-- 合并两条有序链表 -->
<script>
const link1 = new LinkedList()
link1.append(1)
link1.append(3)
link1.append(4)
link1.append(6)
link1.append(7)
const link2 = new LinkedList()
link2.append(2)
link2.append(5)
link2.append(8)
link2.append(9)
function mergerlist(list, otherlist) {
// 1.创建新链表
let newlist = new LinkedList();
let listHead = list.head;
let otherlistHead = otherlist.head;
// 2.比较
// 只要两个链表都还有元素,就继续比较
while (listHead && otherlistHead) {
if (listHead.data < otherlistHead.data) {
// 当第一条链表list指向的data值小于第二条链表otherlist指向的data值
// 在新链表中添加list指向的data值
newlist.append(listHead.data);
listHead = listHead.next;
} else {
// 当第二条链表otherlist指向的data值小于第一条链表list指向的data值
// 在新链表中添加otherlist指向的data值
newlist.append(otherlistHead.data);
otherlistHead = otherlistHead.next;
}
}
// 3.list为空,另一个链表otherlist中的数据依次添加到新链表中
while(otherlistHead){
newlist.append(otherlistHead.data);
otherlistHead = otherlistHead.next
}
// 3.otherlist为空,另一个链表list中的数据依次添加到新链表中
while(listHead){
newlist.append(listHead.data);
listHead = listHead.next
}
return newlist.toString();
}
console.log(mergerlist(link1, link2));
</script>
图解:
LinkedList代码:
<script>
// 封装一个构造函数,用于保存元素和元素的下一个引用
class Londe{
constructor(data){
// 存放数据
this.data=data;
// 指向下一个节点(引用)
this.next=null;
}
}
class LinkList{
constructor(){
this.head=null
this.length=0
}
// 1.append() 向链表最后添加元素
append(ele){
// 创建新节点
let newnode=new Londe(ele);
// 判断头结点是否为空
if(this.head==null){
//头结点指向新节点
this.head=newnode
}else{
// 声明一个current指向头结点的指向
let current=this.head
while(current.next!=null){
// 当current的指向一直不为空时,
// 就随着当时指向的元素节点继续指向它的下一个元素节点
// 直到current的指向为空,就不再执行
current=current.next
}
// 当current 表示最后一个节点时
//令current的指向指向新节点
// 这就是向链表尾部添加新节点
current.next=newnode
}
// 添加了元素,length长度就+1
this.length++
}
// 2.insert(指定位置,插入的元素)
insert(position,ele){
// 位置是否合法
// Number.isInteger():用来判断给定的参数是否为整数
if(position<0||position>this.length||!Number.isInteger(position)){
return false
}
// 创建一个新节点
let newnode=new Londe(ele)
// 2.1在头部位置插入
if(position==0){
if(this.head==null){
// 如果头部指向空,那么就让头部指向新的节点
this.head=newnode
}else{
// 如果头部不为空,
// 那么就先让新节点指向头部指向的节点
// 再让头部指向新节点
newnode.next=this.head
this.head=newnode
}
// 插入了一个新节点,链表中的节点数就+1
this.length++
}else if(position==this.length){
// 2.2在尾部位置插入
// 就直接使用上面的向链表最后添加元素的方法,就行
this.append(ele)
}else{
// 2.3在任意位置插入
// 创建一个变量,让它指向链表中头部指向的节点
let current=this.head;
// 创建一个变量index,方便知道节点的位置,以及current的具体指向节点位置
let index=0
// 前一个节点 position-1位置的节点
while(index<position-1){
// 已知你想要插入节点的准确位置
// 从链表的第一个位置开始比较
// 通过index改变移动current指向的节点
// 直到index=position-1时,结束
current=current.next;
index++
}
// current就是插入节点位置的前一个节点
newnode.next=current.next
current.next=newnode
this.length++
}
}
// 3.removeAt(position) 移除指定位置的元素
removeAt(position){
// 位置是否合法
if(position<0||position>=this.length-1||!Number.isInteger(position)){
return false
}
if(this.head==null){
// 空链表
return
}else{
// 非空链表
if(position==0){
// 移除头部元素
this.head=this.head.next
}else{
// 移除其他位置的元素
let current=this.head,index=0;
while(index<position-1){
// 已知你想要移除节点的准确位置
// 从链表的第一个位置开始比较
// 通过index改变移动current指向的节点
// 直到index=position-1时,结束
current=current.next;
index++
}
// 将移除节点的前面一个节点指向移除节点的后面一个节点
current.next=current.next.next
}
// 移除节点,链表中节点数-1
this.length--
}
}
// 4.indexOf(ele) 查找指定元素的位置,存在返回index,不存在返回-1
indexOf(ele){
let current=this.head,index=0
while(index<this.length){
// 遍历链表中的所有节点
if(current.data==ele){
// 如果current指向的节点中的数据与我们查找的指定元素一致
// 就返回当前current指向的节点的位置
return index
}else{
// 如果current指向的节点中的数据与我们查找的指定元素不一致
// 继续找
// 并且,index位置向后移动,,也就是+1
// current的指向,随着index的位置改变
current=current.next
index++
}
}
// 找完了所有,都没有找到,返回-1
// 表明链表中没有相对应的节点
return -1
}
// 5.remove(ele) 移除指定元素
remove(ele){
// 查询指定元素所在的节点位置
let index=this.indexOf(ele)
// 移除该位置的指定元素
this.removeAt(index)
}
// 6.将链表中的数据连接为字符串
toString(){
let current=this.head,index=0,res="";
while(index<this.length){
// 将current指向的节点的数据连接为字符串
res+="-"+current.data;
current=current.next ;
index++
}
// 利用字符串的slice(start,end)方法, 提取字符串的片断,并在新的字符串中返回被提取的部分。
return res.slice(1)
}
// 7.isEmpty():如果链表中不包含任何元素,返回true,如果链表长度大于0,则返回false。
isEmpty(){
if(this.length==0){
return true
}else{
return false
}
}
// 8.size():返回链表包含的元素个数。与数组的length属性类似。
size(){
return this.length
}
}
</srcipt>