node 获取表单数据 为空_数据结构与算法(python)单向循环链表
單向循環(huán)鏈表
單鏈表的一個(gè)變形是單向循環(huán)鏈表, 鏈表的最后一個(gè)節(jié)點(diǎn)的next域不再為None, 而是指向鏈表的頭節(jié)點(diǎn).
單向循環(huán)鏈表如圖所示:
單向循環(huán)鏈表
同樣單向循環(huán)鏈表也是要使用python來(lái)對(duì)它的基本功能進(jìn)行一個(gè)封裝. 總體大致的功能如下:
- is_empty() 判斷鏈表是否為空
- length() 返回鏈表的長(zhǎng)度
- travel() 遍歷
- add(item) 在頭部添加一個(gè)節(jié)點(diǎn)
- append(item) 在尾部添加一個(gè)節(jié)點(diǎn)
- insert(pos, item) 在指定位置pos添加節(jié)點(diǎn)
- remove(item) 刪除一個(gè)節(jié)點(diǎn)
- search(item) 查找節(jié)點(diǎn)是否存在
注意: 區(qū)別單鏈表的操作如圖:(圖為單鏈表操作)
單鏈表的操作
單向循環(huán)鏈表的操作多了一個(gè)尾部指向頭部的鏈接.
python實(shí)現(xiàn)其基本功能
事先定義一個(gè)節(jié)點(diǎn), 包含數(shù)據(jù)元素的本身和它 的next區(qū)域的指向None.
class Node(object): '''節(jié)點(diǎn) ''' def __init__(self, item): self.item = item self.next = None結(jié)果如下(還是那句話, 寫(xiě)完一個(gè)功能調(diào)試一下):
node節(jié)點(diǎn)運(yùn)行調(diào)試圖
總體功能布局
同樣需要事先初始化節(jié)點(diǎn), 其實(shí)就是對(duì)之前的單鏈表的功能進(jìn)行直接的更改, 可以直接把之前的代碼復(fù)制過(guò)來(lái),看看是否可以滿足單向循環(huán)鏈表的的功能, 如果可以直接過(guò)去就好, 如果不行重新修改. (注意和之前單鏈表的區(qū)別, 循環(huán)的終止點(diǎn), 設(shè)置循環(huán)的終止, 到哪里才算是一次循環(huán)的完成)
class SinCycLinkedlist(object): ''' 單向循環(huán)鏈表 ''' def __init__(self): self.__head = None def is_empty(self): ''' 判斷鏈表是否為空 ''' def length(self): ''' 返回鏈表的長(zhǎng)度 ''' def travel(self): ''' 遍歷鏈表 ''' def add(self, item): ''' 頭部添加節(jié)點(diǎn) ''' def append(self, item): ''' 尾部添加節(jié)點(diǎn) ''' def insert(self, pos, item): ''' 指定位置添加節(jié)點(diǎn) ''' def remove(self, item): ''' 刪除節(jié)點(diǎn) ''' def search(self, item): ''' 查找節(jié)點(diǎn)是否存在 '''if __name__ == "__main__": ll = SinCycLinkedlist()基本功能大致如上.
判斷鏈表是否為空
這功能和之前的單鏈表是一樣的, 只需要判斷頭節(jié)點(diǎn)是否為空, 直接返回True or False就好了.
def is_empty(self): ''' 判斷鏈表是否為空 ''' return self.__head == None返回鏈表長(zhǎng)度
通過(guò)循環(huán)遍歷來(lái)計(jì)算元素的個(gè)數(shù), 沒(méi)遍歷一個(gè)count就加1, 但是這里的循環(huán)的終止條件, 要變, 不能使用之前的. 終止條件改為 cur.next != self.__head 直接判斷最后一個(gè)節(jié)點(diǎn)的下一個(gè)區(qū)域是否指向頭結(jié)點(diǎn), 如果是結(jié)束一次循環(huán), 如果不是繼續(xù)往后遍歷.代碼如下:
def length(self): ''' 返回鏈表的長(zhǎng)度 ''' if self.is_empty(): return 0 count = 1 cur = self.__head while cur.next != self.__head: count += 1 cur = cur.next return count遍歷鏈表打印里面的元素
同樣是和之前的單鏈表的是一樣的, 只是循環(huán)的條件得改掉, 由于是頭尾相連的, 導(dǎo)致之前的cur != None 在非空鏈表中不可以使用每個(gè)元素都是有值的, 沒(méi)有指向None的元素. 每個(gè)元素的next區(qū)域都有指向, 每個(gè)元素cur.next != None也是不可以使用的.所以還是改成cru.next != self.__head以最后一個(gè)節(jié)點(diǎn)和頭節(jié)點(diǎn)作為比較.代碼如下:
def travel(self): ''' 遍歷鏈表 ''' if self.is_empty(): return cur = self.__head print (cur.item) # 頭節(jié)點(diǎn)沒(méi)有參與循環(huán), 要直接打印出來(lái) while cur.next != self.__head: cur = cur.next print (cur.item) print ("") # 換行頭部添加節(jié)點(diǎn)
單向循環(huán)鏈表頭部添加節(jié)點(diǎn)
先定義要添加的節(jié)點(diǎn)node, 判斷是否為空, 如果是空的話, 直接按照頭結(jié)點(diǎn)的添加, 頭節(jié)點(diǎn)指向node, node的next區(qū)域指向頭節(jié)點(diǎn).如果不是, 添加的節(jié)點(diǎn)指向__head, 移到鏈表尾部, 將結(jié)尾部節(jié)點(diǎn)的next指向node. 如代碼:
def add(self, item): ''' 頭部添加節(jié)點(diǎn) '''def travel(self): ''' 遍歷鏈表 ''' if self.is_empty(): return cur = self.__next print (cur.item) # 頭節(jié)點(diǎn)沒(méi)有參與循環(huán), 要直接打印出來(lái) while cur.next != self.__head: cur = cur.next print (cur.item) print ("") # 換行def travel(self): ''' 遍歷鏈表 ''' if self.is_empty(): return cur = self.__next print (cur.item) # 頭節(jié)點(diǎn)沒(méi)有參與循環(huán), 要直接打印出來(lái) while cur.next != self.__head: cur = cur.next print (cur.item) print ("") # 換行 node = Node(item) if self.is_empty(): self.__head = node node.next = self.__head else: # 添加的節(jié)點(diǎn)指向__head node.next = self.__head # 移到鏈表的尾部, 將尾部節(jié)點(diǎn)的next指向node cur = self.__head while cur.next != self.__head: cur = cur.next cur.next = node # __head 指向添加node的 self.__head = node鏈表尾部的添加
和之前的單鏈表差不多, 判斷是否是空鏈表, 如果是頭節(jié)點(diǎn)指向node, node的next區(qū)域指向self.__head, 如果不是, 移動(dòng)到鏈表的尾部, 注意循環(huán)結(jié)束的條件cur.next != self.__head , 找到尾節(jié)點(diǎn)之后將尾節(jié)點(diǎn)指向node, 再將node指向頭節(jié)點(diǎn)__head, 注意指向的先后順序, 先是cur.next指向再是node的next指向, 注意區(qū)分先后順序, 每種指向的區(qū)別, 先后的影響. 代碼如下:
def append(self, item): ''' 尾部添加節(jié)點(diǎn) ''' node = Node(item) if self.is_empty(): self.__head = node node.next = self.__head else: # 移動(dòng)到鏈表的尾部 cur = self.__head while cur.next != self.__head: cur = cur.next # 將尾節(jié)點(diǎn)指向node cur.next = node # 將node的指向頭結(jié)點(diǎn)__head node.next = self.__head區(qū)別單鏈表的尾部添加節(jié)點(diǎn), 區(qū)別注意尾部的指向問(wèn)題. 單鏈表尾部如圖所示:
單鏈表尾部添加, 注意區(qū)別
指定位置添加節(jié)點(diǎn)
基本思路和前面的單鏈表一樣.先判斷插入的位置. 如果是頭部插入直接調(diào)用self.add()函數(shù)就可以 ( 這里使用pos<=0來(lái)表示頭部的插入, 傳遞進(jìn)來(lái)的參數(shù)小于0了, 就認(rèn)為他是要在頭部進(jìn)行插入 ) , 如果是尾部直接調(diào)用前面的self.append()函數(shù)就好 ( 使用pos > self.length - 1 來(lái)表示在尾部插入傳遞進(jìn)來(lái)的參數(shù), 要求的位置超過(guò)了鏈表應(yīng)有的長(zhǎng)度, 就認(rèn)為直接在尾部進(jìn)行插入 ) . 注意pos參數(shù)傳遞過(guò)來(lái), 判斷插入的位置的時(shí)候注意一定要區(qū)別和鏈表本身的長(zhǎng)度之間的區(qū)別, 是加一還是減一. 指定其他位置的插入, 使用count來(lái)計(jì)數(shù), 如果count < pos - 1 接著向后移動(dòng)就可以了 , 如果不滿足條件了, 注意節(jié)點(diǎn)插入的先后順序. 思考為什么是count < pos - 1 而不是正好等于或者加一. 詳細(xì)代碼如下:
def insert(self, pos, item): ''' 指定位置添加節(jié)點(diǎn) ''' if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: node = Node(item) cur = self.__head count = 0 # 移動(dòng)到指定位置的前一個(gè)位置 while count < (pos - 1): count += 1 cur = cur.next node.next = cur.next cur.next = node注意node的插入的先后順序
刪除一個(gè)節(jié)點(diǎn)
這里需要引入pre游標(biāo)來(lái)輔助我們判斷節(jié)點(diǎn), 對(duì)節(jié)點(diǎn)進(jìn)行刪除.
判斷鏈表是否為空, 如果是直接返回, 空鏈表不需要?jiǎng)h除. 如果頭結(jié)點(diǎn)的元素就是要查找的元素item, 進(jìn)入分支判斷, 如果鏈表不止一個(gè)節(jié)點(diǎn), 先找到尾節(jié)點(diǎn), 將尾節(jié)點(diǎn)的next指向第二個(gè)節(jié)點(diǎn)(注意這些節(jié)點(diǎn)之間next區(qū)域移動(dòng)的先后順序, 注意之間的區(qū)別). 如果鏈表只有一個(gè)節(jié)點(diǎn)該怎么辦.
第一個(gè)節(jié)點(diǎn)不是要?jiǎng)h除的, 先找到要?jiǎng)h除的元素, 再通過(guò)區(qū)域的指向來(lái)進(jìn)行刪除. 代碼如下:
def remove(self, item): ''' 刪除節(jié)點(diǎn) ''' # 若鏈表為空 if self.is_empty(): return # 將cur 指向頭節(jié)點(diǎn) cur = self.__head pre = None # 若頭節(jié)點(diǎn)就是要找的 if cur.item == item: # 如果鏈表不止一個(gè)節(jié)點(diǎn) if cur.next != self.__head: # 先找到尾節(jié)點(diǎn), 將尾節(jié)點(diǎn)的next指向第二個(gè)節(jié)點(diǎn) while cur.next != self.__head: cur = cur.next # cur指向了尾節(jié)點(diǎn) cur.next = self.__head.next self.__head = self.__head.next else: # 鏈表只有一個(gè)節(jié)點(diǎn) self.__head = None else: pre = self.__head # 第一個(gè)節(jié)點(diǎn)不是要?jiǎng)h除的 while cur.next != self.__head: # 找到了要?jiǎng)h除的元素 if cur.item == item: # 刪除 pre.next = cur.next return else: pre = cur cur = cur.next # cur指向尾節(jié)點(diǎn) if cur.item == item: # 尾部刪除 pre.next = cur.next查找節(jié)點(diǎn)是否存在
這個(gè)功能和單鏈表中的差不多就是一個(gè)循環(huán)判斷的條件不一樣, 注意新的判斷條件是cur的next區(qū)域是否等于頭節(jié)點(diǎn).詳細(xì)代碼如下:
def search(self, item): ''' 查找節(jié)點(diǎn)是否存在 ''' if self.is_empty(): return False cur = self.__head if cur.item == item: return True while cur.next != self.__head: cur = cur.next if cur.item == item: return True return False最后功能測(cè)試如下:
if __name__ == "__main__": ll = SinCycLinkedlist() ll.add(1) ll.add(2) ll.append(3) ll.insert(2,4) ll.insert(4,5) ll.insert(0,6) print ("length:",ll.length()) ll.travel() print (ll.search(3)) print (ll.search(7)) ll.remove(1) print ("length:", ll.length()) ll.travel()運(yùn)行結(jié)果如下:
鏈表運(yùn)行結(jié)果如圖所示
上傳代碼之后, 縮進(jìn)可能會(huì)有點(diǎn)小問(wèn)題, 注意一定要注意縮進(jìn)
總結(jié)
以上是生活随笔為你收集整理的node 获取表单数据 为空_数据结构与算法(python)单向循环链表的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: opencv c++ 寻找矩形框_基于P
- 下一篇: c++控制台应用每一列数据如何对齐_Py