原题链接:707.设计链表
首先是定义一个MyLinkedList的结构用来管理链表,里面有两个元素一个是*node类型的virhead,虚拟头节点virhead.next指向的是链表的实际头节点
再定义一个node类型的结构体,表示节点,里面有一个val和一个next
类型定义完后,则需要在Constructor内初始化
直接返回一个MyLinkedList类型的node节点,val值为0
Get函数内,首先需要判断索引是否有效,大于链表长度或小于0(当前链表下标从0开始)都是无效的
直接遍历链表直至目标索引,返回当前索引的val即可
代码块:
type MyLinkedList struct {
virhead *node // 虚拟头节点,简化链表操作
len int // 链表总长度
}
type node struct {
val int // 节点值
next *node // 指向下一个节点的指针
}
// Constructor 初始化 MyLinkedList,创建一个虚拟头节点,链表长度设为 0
func Constructor() MyLinkedList {
return MyLinkedList{&node{}, 0} // 返回一个新的 MyLinkedList 实例
}
// Get 返回索引 index 对应的节点值。如果索引无效,返回 -1
func (this *MyLinkedList) Get(index int) int {
if index < 0 || index >= this.len { // 检查索引是否有效
return -1 // 索引无效,返回 -1
}
cur := this.virhead.next // 从虚拟头节点的下一个节点开始遍历
for i := 0; i < index; i++ { // 遍历到目标索引
cur = cur.next // 前进到下一个节点
}
return cur.val // 返回对应索引的节点值
}
// AddAtHead 在链表头部插入一个新节点
func (this *MyLinkedList) AddAtHead(val int) {
newnode := &node{val, this.virhead.next} // 创建新节点,指向当前头节点
this.virhead.next = newnode // 更新虚拟头节点的指针指向新节点
this.len++ // 链表长度加 1
}
// AddAtTail 在链表尾部添加一个新节点
func (this *MyLinkedList) AddAtTail(val int) {
cur := this.virhead // 从虚拟头节点开始
for cur.next != nil { // 遍历到链表末尾
cur = cur.next // 前进到下一个节点
}
newnode := &node{val, nil} // 创建新节点,next 指向 nil
cur.next = newnode // 将最后一个节点的 next 指向新节点
this.len++ // 链表长度加 1
}
// AddAtIndex 在指定索引处插入一个新节点
func (this *MyLinkedList) AddAtIndex(index int, val int) {
if index < 0 { // 如果索引小于 0,插入到链表头部
this.AddAtHead(val)
} else if index == this.len { // 如果索引等于链表长度,追加到末尾
this.AddAtTail(val)
} else if index > this.len { // 如果索引大于链表长度,不进行插入
return
} else { // 正常情况,插入到索引位置
newnode := &node{val, nil} // 创建新节点
cur := this.virhead // 从虚拟头节点开始遍历
for i := 0; i < index; i++ { // 遍历到目标索引的前一个节点
cur = cur.next // 前进到下一个节点
}
newnode.next = cur.next // 新节点指向当前节点的下一个节点
cur.next = newnode // 当前节点的 next 指向新节点,完成插入
this.len++ // 链表长度加 1
}
}
// DeleteAtIndex 删除指定索引的节点
func (this *MyLinkedList) DeleteAtIndex(index int) {
if index >= this.len || index < 0 { // 检查索引有效性
return // 索引无效,不进行删除
}
cur := this.virhead // 从虚拟头节点开始
for i := 0; i < index; i++ { // 遍历到目标索引的前一个节点
cur = cur.next // 前进到下一个节点
}
if cur.next != nil { // 确保要删除的节点存在
cur.next = cur.next.next // 跳过要删除的节点
}
this.len-- // 删除节点后链表长度减 1
}