经典链表删除题。原课程中题目过于简单,此处用leetcode代替
删除结点
先说203,要求删除链表中所有值为val的结点。那么主要就有2种做法:迭代+递归
迭代
迭代也可以有多种实现。根据头结点分为头结点额外考虑,或者新增头结点;根据迭代方式分为用2个指针指向前一结点和当前结点,或者只用一个指针完成。这里实现2种:
//实现1:考虑头结点为应删除结点的情况,且只使用pre指针
func removeElements(head *ListNode, val int) *ListNode {
for head != nil && head.Val == val {
head = head.Next
}
if head == nil{
return head
}
pre := head
for pre.Next != nil{
if pre.Next.Val == val{
pre.Next = pre.Next.Next
}else{
pre = pre.Next
}
}
return head
}
//实现2:新增一个头结点,且使用pre和cur两个指针
func removeElements(head *ListNode, val int) *ListNode {
root := &ListNode{}
root.Next = head
pre, cur := root, root.Next
for cur != nil{
if cur.Val == val{
pre.Next = cur.Next
cur = nil
cur = pre.Next
}else{
pre = pre.Next
cur = cur.Next
}
}
return root.Next
}
递归
对于应该删除的结点,直接对它的next结点向下递归;对于不应删除的结点,Next指针指向递归的结果。边界条件就是遇到空指针的情况。
代码:
func removeElements(head *ListNode, val int) *ListNode {
if head == nil{
return nil
}
if head.Val == val{
return removeElements(head.Next, val)
}else{
head.Next = removeElements(head.Next, val)
return head
}
}
单个结点删除
leetcode237题,只给一个指针,怎么把它从链表中删除?
答案是把下一个结点的值赋值给它,然后把下一个结点删除
代码:
func deleteNode(node *ListNode) {
node.Val = node.Next.Val
node.Next = node.Next.Next
}