亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Python雙向循環(huán)鏈表實(shí)現(xiàn)方法分析

 更新時(shí)間:2018年07月30日 08:59:59   作者:稀里糊涂林老冷  
這篇文章主要介紹了Python雙向循環(huán)鏈表,結(jié)合實(shí)例形式分析了Python雙向鏈表的定義、遍歷、添加、刪除、搜索等相關(guān)操作技巧,需要的朋友可以參考下

本文實(shí)例講述了Python雙向循環(huán)鏈表實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:

最近身邊的朋友在研究用python來實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)。遇到一個問題就是雙向循環(huán)鏈表的實(shí)現(xiàn),改指向的時(shí)候總是發(fā)蒙。

我自己嘗實(shí)現(xiàn)了一個python的雙向循環(huán)鏈表。附上代碼,希望對大家有幫助。

如果不懂什么是雙向循環(huán)鏈表的伙伴,需要補(bǔ)習(xí)一下數(shù)據(jù)結(jié)構(gòu)的基礎(chǔ)之后哦~~~

在python當(dāng)中 用一個類Node 來實(shí)現(xiàn)鏈表的節(jié)點(diǎn),節(jié)點(diǎn)數(shù)據(jù)有三個變量:

  • prev:前驅(qū)指針: 用于指向當(dāng)前節(jié)點(diǎn)前一個節(jié)點(diǎn)
  • next: 后繼指針  用于指向當(dāng)前節(jié)點(diǎn)后一個節(jié)點(diǎn)
  • item: 值, 用于存儲該節(jié)點(diǎn)要存的數(shù)值

當(dāng)前節(jié)點(diǎn)的前一個節(jié)點(diǎn)我們叫他前驅(qū),后一個節(jié)點(diǎn)我們叫他后繼。

在鏈表類當(dāng)中,我們有一個變量head是鏈表的頭指針

我們拿著鏈表的頭head,就可以對他進(jìn)行一些列操作:( 由于是雙向循環(huán)鏈表,修改指針特別容易出錯,我盡量說的細(xì)致,方便大家參考)

判斷空:is_empty()

如果頭指針head沒有指向則鏈表是空的 否則不是空的

在頭部添加元素: add(item)

1 新建一個節(jié)點(diǎn) 里面的值是item。

2 放入頭部:

2.1 如果鏈表是空的,node的next和prev都指向自己,然后head再指向node

在尾部添加元素: append(item)

1 創(chuàng)建一個新節(jié)點(diǎn)node 里面的值是item

2 放入尾部:

2.1 如果鏈表空,則執(zhí)行頭部添加add就可以

2.2 鏈表非空:

2.2.1 node的next指向head

2.2.2 node的prev指向head的prev

2.2.3 head的prev元素的next指向node

2.2.4 head的prev指向改為node

2.2.5 head指向node  更換了頭部

指定位置添加元素: insert( pos , item )

1 新建一個節(jié)點(diǎn)node 里面的值是item

2 找到合適的位置插進(jìn)去:

2.1 如果pos <= 0 還小,那就執(zhí)行頭插方法 add()

2.2 如果pos >= 鏈表長度, 那就執(zhí)行尾部插入 append()

2.3 如果pos位置在鏈表的中間:

2.3.1 定義一個臨時(shí)變量temp 按照傳入的pos找到要插入的位置的前一個元素

2.3.2 node的prev設(shè)為temp,node的next設(shè)為temp的next

2.3.3 temp的next指向的節(jié)點(diǎn)的prev改為node

2.3.4 temp的next改為node

得到鏈表長度: length()

1 我們設(shè)置一個臨時(shí)變量temp初始設(shè)為head , 設(shè)置一個計(jì)數(shù)器count 初始為 0

2 令count自增1 然后temp改指向自己的下一個元素 一直到temp遇到None 為止,temp到了鏈表的最后一個元素

通過這樣的方式,統(tǒng)計(jì)出一共有多少個節(jié)點(diǎn)返回

遍歷鏈表數(shù)據(jù): travelji()

1 設(shè)置一個臨時(shí)變量temp初始化設(shè)為head

2 temp 每次輸出自己指向元素的值,然后在指向自己的下一個元素,一直temp為None 說明到了列表的尾部

刪除鏈表元素: remove( item )

1 開啟temp臨時(shí)變量 初始化為head ,

2  temp不斷指向自己的下一個元素,每次指向一個元素都檢查當(dāng)前值是不是item,如果找到item則刪除它返回True,如果沒找到就到尾部了就返回False

2.1 刪除過程:

2.1.1 temp的前一個元素的next改為temp的后一個元素

2.1.2 temp的后一個元素的prev改為前一個元素

查詢是否有元素:search()

設(shè)置一個臨時(shí)變量temp從head開始,不斷指向自己下一個,每次都檢查一下自己的值如果和item相同返回True結(jié)束

如果temp變成None 則到尾部了都沒找到 返回False

上代碼!

# -*- coding:utf-8 -*-
#!python3
#鏈表的節(jié)點(diǎn)
class Node(object):
 def __init__(self , item ):
  self.item = item #節(jié)點(diǎn)數(shù)值
  self.prev = None #用于指向前一個元素
  self.next = None #用于指向后一個元素
#雙向循環(huán)鏈表
class DoubleCircleLinkList(object):
 def __init__(self):
  self.__head = None #初始化的時(shí)候頭節(jié)點(diǎn)設(shè)為空、
 #判斷鏈表是否為空,head為None 的話則鏈表是空的
 def is_empty(self):
  return self.__head is None
 #頭部添加元素的方法
 def add(self,item):
  node = Node(item) #新建一個節(jié)點(diǎn)node 里面的值是item
  # 如果鏈表是空的,則node的next和prev都指向自己(因?yàn)槭请p向循環(huán)),head指向node
  if self.is_empty():
   self.__head = node
   node.next = node
   node.prev = node
  # 否則鏈表不空
  else:
   node.next = self.__head #node的next設(shè)為現(xiàn)在的head
   node.prev = self.__head.prev #node的prev 設(shè)為現(xiàn)在head的prev
   self.__head.prev.next = node #現(xiàn)在head的前一個元素的next設(shè)為node
   self.__head.prev = node #現(xiàn)在head的前驅(qū) 改為node
   self.__head = node #更改頭部指針
 #尾部添加元素方法
 def append(self , item):
  #如果當(dāng)前鏈表是空的 那就調(diào)用頭部插入方法
  if self.is_empty():
   self.add(item)
  #否則鏈表不為空
  else :
   node = Node(item) #新建一個節(jié)點(diǎn)node
   #因?yàn)槭请p向循環(huán)鏈表,所以head的prev其實(shí)就是鏈表的尾部
   node.next = self.__head #node的下一個設(shè)為頭
   node.prev = self.__head.prev #node的前驅(qū)設(shè)為現(xiàn)在頭部的前驅(qū)
   self.__head.prev.next = node #頭部前驅(qū)的后繼設(shè)為node
   self.__head.prev = node #頭部自己的前驅(qū)改為node
 #獲得鏈表長度 節(jié)點(diǎn)個數(shù)
 def length(self):
  #如果鏈表是空的 就返回0
  if self.is_empty():
   return 0
  #如果不是空的
  else:
   cur = self.__head #臨時(shí)變量cur表示當(dāng)前位置 初始化設(shè)為頭head
   count = 1 #設(shè)一個計(jì)數(shù)器count,cur每指向一個節(jié)點(diǎn),count就自增1 目前cur指向頭,所以count初始化為1
   #如果cur.next不是head,說明cur目前不是最后一個元素,那么count就1,再讓cur后移一位
   while cur.next is not self.__head:
    count += 1
    cur = cur.next
   #跳出循環(huán)說明所有元素都被累加了一次 返回count就是一共有多少個元素
   return count
 #遍歷鏈表的功能
 def travel(self):
  #如果當(dāng)前自己是空的,那就不遍歷
  if self.is_empty():
   return
  #鏈表不空
  else :
   cur = self.__head #臨時(shí)變量cur表示當(dāng)前位置,初始化為鏈表的頭部
   #只要cur的后繼不是頭說明cur不是最后一個節(jié)點(diǎn),我們就輸出當(dāng)前值,并讓cur后移一個節(jié)點(diǎn)
   while cur.next is not self.__head:
    print( cur.item,end=" " )
    cur = cur.next
   #當(dāng)cur的后繼是head的時(shí)候跳出循環(huán)了,最后一個節(jié)點(diǎn)還沒有打印值 在這里打印出來
   print( cur.item )
 #置頂位置插入節(jié)點(diǎn)
 def insert(self, pos , item ):
  #如果位置<=0 則調(diào)用頭部插入方法
  if pos <= 0:
   self.add(item)
  #如果位置是最后一個或者更大 就調(diào)用尾部插入方法
  elif pos > self.length() - 1 :
   self.append(item)
  #否則插入位置就是鏈表中間
  else :
   index = 0 #設(shè)置計(jì)數(shù)器,用于標(biāo)記我們后移了多少步
   cur = self.__head #cur標(biāo)記當(dāng)前所在位置
   #讓index每次自增1 ,cur后移,當(dāng)index=pos-1的時(shí)候說明cur在要插入位置的前一個元素,這時(shí)候停下
   while index < pos - 1 :
    index += 1
    cur = cur.next
   #跳出循環(huán),cur在要插入位置的前一個元素,將node插入到cur的后面
   node = Node(item) #新建一個節(jié)點(diǎn)
   node.next = cur.next #node的后繼設(shè)為cur的后繼
   node.prev = cur #node的前驅(qū)設(shè)為cur
   cur.next.prev = node #cur后繼的前驅(qū)改為node
   cur.next = node #cur后繼改為node
 #刪除節(jié)點(diǎn)操作
 def remove(self,item):
  #如果鏈表為空 直接不操作
  if self.is_empty():
   return
  #鏈表不為空
  else:
   cur = self.__head #臨時(shí)變量標(biāo)記位置,從頭開始
   #如果頭結(jié)點(diǎn)就是 要刪除的元素
   if cur.item == item:
    #如果只有一個節(jié)點(diǎn) 鏈表就空了 head設(shè)為None
    if self.length() == 1:
     self.__head = None
    #如果多個元素
    else:
     self.__head = cur.next #頭指針指向cur的下一個
     cur.next.prev= cur.prev #cur后繼的前驅(qū)改為cur的前驅(qū)
     cur.prev.next = cur.next #cur前驅(qū)的后繼改為cur的后繼
   #否則 頭節(jié)點(diǎn)不是要刪除的節(jié)點(diǎn) 我們要向下遍歷
   else:
    cur = cur.next #把cur后移一個節(jié)點(diǎn)
    #循環(huán)讓cur后移一直到鏈表尾元素位置,期間如果找得到就刪除節(jié)點(diǎn),找不到就跳出循環(huán),
    while cur is not self.__head:
     #找到了元素cur就是要刪除的
     if cur.item == item:
      cur.prev.next = cur.next #cur的前驅(qū)的后繼改為cur的后繼
      cur.next.prev = cur.prev #cur的后繼的前驅(qū)改為cur的前驅(qū)
     cur = cur.next
 #搜索節(jié)點(diǎn)是否存在
 def search(self , item):
  #如果鏈表是空的一定不存在
  if self.is_empty():
   return False
  #否則鏈表不空
  else:
   cur = self.__head #設(shè)置臨時(shí)cur從頭開始
   # cur不斷后移,一直到尾節(jié)點(diǎn)為止
   while cur.next is not self.__head:
    #如果期間找到了就返回一個True 結(jié)束運(yùn)行
    if cur.item == item:
     return True
    cur = cur.next
   # 從循環(huán)跳出來cur就指向了尾元素 看一下為元素是不是要找的 是就返回True
   if cur.item ==item:
    return True
   #所有元素都不是 就返回False 沒找到
   return False
if __name__ == "__main__":
 dlcl = DoubleCircleLinkList()
 print(dlcl.search(7))
 dlcl.travel()
 dlcl.remove(1)
 print(dlcl.length())
 print(dlcl.is_empty())
 dlcl.append(55)
 print(dlcl.search(55))
 dlcl.travel()
 dlcl.remove(55)
 dlcl.travel()
 print(dlcl.length())
 dlcl.add(3)
 print(dlcl.is_empty())
 dlcl.travel()
 dlcl.add(4)
 dlcl.add(5)
 dlcl.append(6)
 dlcl.insert(-10,1)
 dlcl.travel()
 print(dlcl.length())
 dlcl.remove(6)
 dlcl.travel()
 print(dlcl.search(7) )
 dlcl.append(55)
 dlcl.travel()

運(yùn)行結(jié)果:

False
0
True
True
55
0
False
3
1 5 4 3 6
5
1 5 4 3
False
1 5 4 3 55

各種數(shù)據(jù)結(jié)構(gòu)主要是思想,不同的人實(shí)現(xiàn)方式都不一定一樣,同一個人多次實(shí)現(xiàn)也不一定一樣。所以以上代碼僅供參考~

如果有更簡潔的方式,歡迎大家批評指正哦~

更多關(guān)于Python相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《Python數(shù)據(jù)結(jié)構(gòu)與算法教程》、《Python編碼操作技巧總結(jié)》、《Python函數(shù)使用技巧總結(jié)》、《Python字符串操作技巧匯總》及《Python入門與進(jìn)階經(jīng)典教程

希望本文所述對大家Python程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • Python OpenCV 基于圖像邊緣提取的輪廓發(fā)現(xiàn)函數(shù)

    Python OpenCV 基于圖像邊緣提取的輪廓發(fā)現(xiàn)函數(shù)

    這篇文章主要介紹了Python OpenCV 基于圖像邊緣提取的輪廓發(fā)現(xiàn)函數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-03-03
  • numpy降維方法

    numpy降維方法

    本文主要介紹了numpy降維方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-02-02
  • 如何解決pytorch訓(xùn)練過程中CPU內(nèi)存溢出問題

    如何解決pytorch訓(xùn)練過程中CPU內(nèi)存溢出問題

    這篇文章主要介紹了如何解決pytorch訓(xùn)練過程中CPU內(nèi)存溢出問題,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • wxpython繪制音頻效果

    wxpython繪制音頻效果

    這篇文章主要為大家詳細(xì)介紹了wxpython繪制音頻效果,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • 使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果

    使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果

    這篇文章主要介紹了使用python tkinter實(shí)現(xiàn)各種個樣的撩妹鼠標(biāo)拖尾效果,本文通過實(shí)例代碼,給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 淺談Python處理PDF的方法

    淺談Python處理PDF的方法

    這篇文章主要介紹了Python處理PDF的兩種方法代碼示例,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • Python+Matplotlib繪制發(fā)散條形圖的示例代碼

    Python+Matplotlib繪制發(fā)散條形圖的示例代碼

    發(fā)散條形圖(Diverging Bar)是一種用于顯示數(shù)據(jù)分布的圖表,可以幫助我們比較不同類別或分組的數(shù)據(jù)的差異和相對性,本文介紹了Matplotlib繪制發(fā)散條形圖的函數(shù)源碼,需要的可以參考一下
    2023-06-06
  • python實(shí)現(xiàn)web應(yīng)用框架之增加動態(tài)路由

    python實(shí)現(xiàn)web應(yīng)用框架之增加動態(tài)路由

    這篇文章主要介紹web應(yīng)用框架如何添加動態(tài)路由,在我們編寫的框架中,我們添加動態(tài)路由,是使用了正則表達(dá)式,同時(shí)在注冊的時(shí)候,需要注明該路由是請求路由,文中有詳細(xì)的代碼示例,需要的朋友可以參考下
    2023-05-05
  • 詳解如何利用Python實(shí)現(xiàn)報(bào)表自動化

    詳解如何利用Python實(shí)現(xiàn)報(bào)表自動化

    這篇文章主要介紹了報(bào)表自動化的流程,并教你用Python實(shí)現(xiàn)工作中的一個報(bào)表自動化實(shí)戰(zhàn),文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解一下
    2023-03-03
  • python線程信號量semaphore使用解析

    python線程信號量semaphore使用解析

    這篇文章主要介紹了python線程信號量semaphore使用解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11

最新評論