數據結構和算法----鏈表

  • 鏈表的定義

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是通過鏈表中的指針鏈接次序實現的。

  • 鏈表類型
  1. 單鏈表

  1. 雙鏈表

    

  1. 循環鏈表

  1. 雙向循環鏈表

  • 時間複雜度
  1. 單鏈表

1)、插入操作只需要改變相鄰節點的指針就可以,例如將a插入n位置只需將n-1位置的next指針指向a,將anext指針指向n+1。整個操作的時間複雜度爲O(1)

2)、刪除操作同理只需改變,相鄰節點的指針

       3)、查詢操作最壞時間複雜度爲O(n),與數組的連續存儲空間,只需要首地址和下標就能計算出對應的內存地址不同,鏈表需要根據指針一個節點一個節點地依次遍歷之後才能知道想要查找的數據的相應節點的內存地址。時間複雜度爲O(n)

     2、雙鏈表

        相對與單鏈表,雙鏈表多了個前驅指針。由此可知雙鏈表比單鏈表佔用更多的內存空間

        1)、插入操作與單鏈表類似,只不過單鏈表插入時。需要遍歷查找到該節點和插入節點的前驅節點。雖然插入和刪除操作O(1)但查找該節點的操作爲O(n),雙鏈表因爲有前驅指針所以不需要重新遍歷就可以找到前驅節點

        2)、刪除操作同理,雖然同爲O(1)的時間複雜度,但是理論上雙鏈表會比單鏈錶快一倍。

      3、循環鏈表

         與單鏈表類似,只不過循環鏈表從鏈尾到鏈頭比較方便。適合處理一些循環結構的數據。例如約瑟夫環

  1. 雙向循環鏈表

就是雙向鏈表加循環鏈表,如果上面的理解了,這個就比較好理解

  • 深入理解
  1. 指針

C語言中稱爲指針,pythonjava中稱爲引用。其功能都是存儲期所指向的對象的內存地址

  1. 哨兵簡化鏈表實現難度

針對鏈表的插入、刪除操作,需要對插入第一個結點和刪除最後一個節點的情況進行特殊處理。

  • python代碼實現

定義鏈表,並實現單鏈表反轉。以後會添加其他相關代碼

class Node(object):
   
def __init__(self,data,next=None):
       
self.data = data
       
self.next = next
class MyLink(object):
   
def __init__(self,data):
       
# 尾指針指向最後一個節點,不包括頭結點
       
self.headnode = Node(None)
       
self.rear = None
        #
定義鏈表
        for
d in data:
            NewNode = Node(d)
           
if self.rear is None:
               
self.rear = NewNode
               
self.headnode.next = NewNode
           
else:
               
self.rear.next = NewNode
               
self.rear = NewNode
    #
打印鏈表
   
def print_all(self):
        next =
self.headnode.next
       
while next is not None:
           
print(next.data,end=' ')
            next = next.next
       
print()

   
# 頭插法實現反轉
   
def reverse(self):
       
# 將鏈表的頭結點之後的元素分開來
       
next = self.headnode.next
       
self.headnode.next = None

        while
next is not None:
            NewNode = next
            next = next.next
            NewNode.next =
self.headnode.next
           
self.headnode.next = NewNode

   
# 遞歸實現
   
def reverse2(self):
        next =
self.headnode.next
       
self.print_next(next)
       
print()

   
def print_next(self,next):
       
if next is None:
           
return

       
self.print_next(next.next)
       
print(next.data,end=' ')

   
def get_last_k_node(self,k):
        advance_node =
self.headnode.next
        behind_node =
self.headnode.next
       
while k>0:
           
if advance_node is None:
               
return None
           
advance_node = advance_node.next
            k -=
1
       
while advance_node is not None:
            advance_node = advance_node.next
            behind_node = behind_node.next

       
return behind_node.data


def main():
    data = [
1,2,3,4,5]
    queue = MyLink(data)
    queue.print_all()
   
print(queue.get_last_k_node(1))
    queue.reverse2()
    queue.reverse()
    queue.print_all()



if __name__ == '__main__':
    main()

鏈表中環檢測

class Node():
    def __init__(self,data,next=None):
        self.data = data
        self.next = next
class MyLink(object):
    def __init__(self,data):
        self.headnode = Node(None)
        self.rear = None
        for d in data:
            NewNode = Node(d)
            if self.rear is None:
                self.rear = NewNode
                self.headnode.next = NewNode
            else:
                self.rear.next = NewNode
                self.rear = NewNode
        #self.rear.next = self.headnode 
    def cry(self):
        slow , fast = self.headnode ,self.headnode
        while fast and fast.next:
            slow = slow.next
            fast = fast.next.next
            if slow == fast:
                 return True
        return False
if __name__ == "__main__":
     data = [1,2,3,4,56,7]
     ml = MyLink(data)
     print(ml.cry())

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章