题目描述
设计链表的实现。您可以选择使用单链表或双链表。单链表中的节点应该具有两个属性:val 和 next。val 是当前节点的值,next 是指向下一个节点的指针/引用。如果要使用双向链表,则还需要一个属性 prev 以指示链表中的上一个节点。假设链表中的所有节点都是 0-index 的。
在链表类中实现这些功能:
- get(index):获取链表中第 index 个节点的值。如果索引无效,则返回-1。
- addAtHead(val):在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
- addAtTail(val):将值为 val 的节点追加到链表的最后一个元素。
- addAtIndex(index,val):在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。如果index小于0,则在头部插入节点。
- deleteAtIndex(index):如果索引 index 有效,则删除链表中的第 index 个节点。
示例:
MyLinkedList linkedList = new MyLinkedList();
linkedList.addAtHead(1);
linkedList.addAtTail(3);
linkedList.addAtIndex(1,2); //链表变为1-> 2-> 3
linkedList.get(1); //返回2
linkedList.deleteAtIndex(1); //现在链表是1-> 3
linkedList.get(1); //返回3
提示:
- 所有val值都在 [1, 1000] 之内。
- 操作次数将在 [1, 1000] 之内。
- 请不要使用内置的 LinkedList 库。
来源:力扣(LeetCode) 链接:leetcode-cn.com/problems/de… 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
解题思路
设计单向链表 用对象嵌套来实现链表 创建链表的构造函数MyLinkedList包含
- 一个辅助创建节点的构造函数listNode,其中包括val属性储存节点的值,next属性储存指向下一个节点的指针
- head属性,保存头部节点
- length属性,保存链表长度
代码
var MyLinkedList = function() {
//创建节点类
this.listNode=function (val,next){
this.val=val;
this.next=next;
}
this.head=null;//头部节点
this.length=0;//记录长度属性
};
/** 获取链表中第 index 个节点的值。如果索引无效,则返回-1
* @param {number} index
* @return {number}
*/
MyLinkedList.prototype.get = function(index) {
if(index<0) return -1;
let i=0;
let current=this.head;
while(current&&i<=index){
if(i===index){//遍历寻找index索引的节点
return current.val;
}
current=current.next;
i++;
}
return -1;//没找到
};
/** 在链表的第一个元素之前添加一个值为 val 的节点。插入后,新节点将成为链表的第一个节点。
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtHead = function(val) {
let node=new this.listNode(val,null);//创建新节点
node.next=this.head;//新节点next,指向头部节点
this.head=node;//头部节点属性赋值新节点
this.length++;
};
/** 将值为 val 的节点追加到链表的最后一个元素。
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtTail = function(val) {
let node=new this.listNode(val,null);//创建新节点
if(!this.head){
//头部节点不存在,就直接赋值this.head
this.head=node;
this.length++;
return;
}
let current=this.head;
while(current.next){
//遍历到尾节点
current=current.next;
}
current.next=node;
this.length++;
};
/**
*在链表中的第 index 个节点之前添加值为 val 的节点。如果 index 等于链表的长度,则该节点将附加到链表的末尾。如果 index 大于链表长度,则不会插入节点。
*如果index小于0,则在头部插入节点。
* @param {number} index
* @param {number} val
* @return {void}
*/
MyLinkedList.prototype.addAtIndex = function(index, val) {
if(index<=0){
//小于零直接调用插入链表头部
this.addAtHead(val);
}else if(index===this.length){
//index等于长度,插入末尾
this.addAtTail(val);
}else if(index<=(this.length-1)){
let i=0;
let current=this.head;
let pre;
while(current&&i<=index){
if(i===index){//遍历寻找index索引的节点
let node=new this.listNode(val,null);//创建新节点
node.next=current;
pre.next=node;
i++;
this.length++;
return;
}
pre=current;
current=current.next;
i++;
}
S
}
console.log(this.head)
};
/** 如果索引 index 有效,则删除链表中的第 index 个节点
* @param {number} index
* @return {void}
*/
MyLinkedList.prototype.deleteAtIndex = function(index) {
if(index>(this.length-1)) return;
if(index===0){
//删除的节点,是头部节点
this.head=this.head.next;
return;
}
let i=0;
let current=this.head;
let pre;
while(current&&i<=index){
if(i===index){//遍历寻找index索引的节点
pre.next= current.next;//父节点的next和子节点的next直接相连,跳过当前节点
}
pre=current;//保存父节点
current=current.next;
i++;
}
this.length--;
};
/**
* Your MyLinkedList object will be instantiated and called as such:
* var obj = new MyLinkedList()
* var param_1 = obj.get(index)
* obj.addAtthis.head(val)
* obj.addAtTail(val)
* obj.addAtIndex(index,val)
* obj.deleteAtIndex(index)
*/