leetcode-explore-learn-數據結構-鏈表4
- 雙鏈表的設計
本系列博文為leetcode-explore-learn子欄目學習筆記,如有不詳之處,請參考leetcode官網:https://leetcode-cn.com/explore/learn/card/linked-list/
所有例題的編程語言為python
雙鏈表的設計
雙鏈表的節點類:
class ListNode:def __init__(self,x):self.val=xself.next=Noneself.prev=None
在鏈表類中實現以下功能:
1.get(index):獲取第index個節點的值,如果索引無效則返回-1
–index從0開始,因此初始化curr=self.head之后,需要往后在操作index+1次即[0,index]
2.addAtHead(val):在鏈表的第一個元素之前家一個值為val的節點,插入后,新節點將成為鏈表的第一個節點。
–pred=self.head(偽頭節點),succ=self.head.next
3.addAtTail(val):將值為val的節點追加到鏈表的最后一個元素
–succ=self.tial(偽尾節點),pred=self.tail.prev
4.addAtIndex(index,val):在鏈表中的第index個節點之前加入值為val的節點,如果index等于鏈表長度,則該節點將附加于鏈表的末尾。如果index大于鏈表的長度則不會加入節點。如果index小于0,則在頭部添加節點。
–第index個節點為succ節點,index-1個節點為pred節點。
–從前往后:pred=self.head(初始化)再操作[0,index-1]次;
–由后往前:succ=self.tail(初始化)再操作[index,size-1]次(size-index次)
5.deleteAtIndex(index):如果索引index有效,則刪除鏈表中的第index個節點。
–由前往后:找到第index-1個節點為pred [0,inde1],succ=pred.next.next;
–由后往前:找到index+1個節點為succ.
class ListNode:def __init__(self,x):self.val=xself.next=Noneself.prev=Noneclass MyLinkedList(object):def __init__(self):"""Initialize your data structure here."""self.size=0self.head,self.tail=ListNode(0),ListNode(0)self.head.next=self.tail # 這兩句的作用是什么,變成一個環?self.tail.prev=self.headdef get(self, index):"""Get the value of the index-th node in the linked list. If the index is invalid, return -1.:type index: int:rtype: int"""if index<0 or index>=self.size:return -1if index+1<self.size-index:curr=self.headfor _ in range(index+1): # [0,index]curr=curr.nextelse:curr=self.tailfor _ in range(self.size-index):curr=curr.prevreturn curr.valdef addAtHead(self, val):"""Add a node of value val before the first element of the linked list. After the insertion, the new node will be the first node of the linked list.:type val: int:rtype: None"""pred,succ=self.head,self.head.nextself.size+=1to_add=ListNode(val)to_add.prev=predto_add.next=succpred.next=to_addsucc.prev=to_adddef addAtTail(self, val):"""Append a node of value val to the last element of the linked list.:type val: int:rtype: None"""succ,pred=self.tail,self.tail.prevself.size+=1to_add=ListNode(val)to_add.prev=predto_add.next=succpred.next=to_addsucc.prev=to_adddef addAtIndex(self, index, val):"""Add a node of value val before the index-th node in the linked list. If index equals to the length of linked list, the node will be appended to the end of linked list. If index is greater than the length, the node will not be inserted.:type index: int:type val: int:rtype: None"""if index>self.size:returnif index<0:index=0if index<self.size-index:pred=self.headfor _ in range(index):pred=pred.nextsucc=pred.nextelse:succ=self.tailfor _ in range(self.size-index):succ=succ.prev#print(succ.val)pred=succ.prevself.size+=1to_add=ListNode(val)#print(pred.val,succ.val,to_add.val)to_add.prev=predto_add.next=succpred.next=to_addsucc.prev=to_adddef deleteAtIndex(self, index):"""Delete the index-th node in the linked list, if the index is valid.:type index: int:rtype: None"""if index<0 or index>=self.size:returnif index<self.size-index:pred=self.headfor _ in range(index):pred=pred.nextsucc=pred.next.nextelse:succ=self.tailfor _ in range(self.size-index-1):succ=succ.prevpred=succ.prev.prevself.size-=1pred.next=succsucc.prev=pred
注意點:刪除插入,最重要的是找到前驅和后繼節點,可以雙向操作之后需要判斷由前往后,還有由后往前。