node 获取表单数据 为空_数据结构与算法(python)单向链表篇
鏈表
數據表的構建需要預先知道數據的大小來申請連續的存儲空間, 而在進行擴充的時候又需要進行數據的搬遷, 使用起來不是很靈活.
鏈表結構可以充分利用計算機內存空間, 實現靈活的內存動態管理. 簡單來說就是, 需要存儲一個數據就隨機分配一個地址空間.
定義
鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是不像順序表一樣連續存儲數據,而是在每一個節點(數據存儲單元)里存放下一個節點的位置信息(即地址)。
鏈表圖
單向鏈表
單向鏈表也叫單鏈表, 是鏈表中最簡單的一種形式,它的每個節點包含兩個域,一個信息域(元素域)和一個鏈接域。這個鏈接指向鏈表中的下一個節點,而最后一個節點的鏈接域則指向一個空值。
單鏈表的節點和單鏈表
表元素域elem用來存放具體的數據。鏈接域next用來存放下一個節點的位置(python中的標識)變量p指向鏈表的頭節點(首節點)的位置,從p出發能找到表中的任意節點。簡單來說如圖:
單鏈表的節點及單鏈表
節點的實現
首先需要定義一個節點, 需要一個__item來存放數據元素, __next來指向下一個節點.
class Node(object): '''單鏈表的節點''' def __init__(self, elem): # 存放數據元素 self.elem = elem # 指向下一個數據地址 self.next = None運行結果圖(建議每寫完一個功能就調試一遍, 免得最后一起調試的時候問題太多, 保持好習慣. 我這里一個一個上截圖太麻煩了, 在寫了很多遍的結果上,就直接上最后的調試截圖了):
node運行結果圖
單鏈表的操作
將單鏈表的的常用操作功能進行封裝
常見的單鏈表操作功能如下所示:
- is_empty() 鏈表是否為空
- length() 鏈表長度
- travel() 遍歷整個鏈表
- add(item) 鏈表頭部添加元素
- append(item) 鏈表尾部添加元素
- insert(pos, item) 指定位置添加元素
- remove(item) 刪除節點
- search(item) 查找節點是否存在
單鏈表的實現
大致的功能如下: 初始化一個節點如果有參數傳進來就是非空, 沒有參數的傳遞就是空節點.
class SingleLinkList(object): '''單鏈表''' def __init__(self, node=None): self.__head = node def is_empty(self): '''判斷單鏈表是否為空''' def length(self): '''需要鏈表的長度''' def travel(self): '''遍歷鏈表''' def add(self, item): '''鏈表的頭部添加元素''' def append(self, item): '''鏈表的尾部添加元素, 尾插法''' def insert(self, pos, item): '''鏈表的指定位置添加元素''' def remove(self, item): '''鏈表刪除節點''' def search(self, item): '''鏈表搜索元素'''if __name__ == "__main__": ll = SingleLinkList()判斷鏈表是否為空
直接通過頭結點的判斷, 看看是否為空. 如果頭結點是None, 那么這個鏈表也就是空.
def is_empty(self): '''判斷單鏈表是否為空''' return self.__head == None判斷鏈表的長度
對鏈表進行遍歷, 每遍歷一個元素count 加一, 直到數據區為none.
def length(self): '''需要鏈表的長度''' # cur 初始時間指向頭節點 cur = self.__head count = 0 # 尾節點指向None, 當達到尾部時 while cur != None: count += 1 # 將cur向后移動一個節點 cur = cur.next return count遍歷列表打印全部元素
同樣是遍歷鏈表, 遇見一個列表打印一個元素, 使用cur = cur.next來對鏈表進行移動.
def travel(self): '''遍歷鏈表''' cur = self.__head while cur != None: print (cur.elem, end = " ") cur = cur.next print ('')頭部添加元素
頭部添加節點元素
插入節點的next區域指向當前鏈表的頭部, sefl.__head指向node的頭部區域
def add(self, item): '''鏈表的頭部添加元素''' node = Node(item) node.next = self.__head self.__head = node尾部添加節點元素
直接把最后的元素的next區域指向node節點的頭部區域, node節點的next區域已經是none了. 如果是空直接self.__head指向新的節點.
def append(self, item): '''鏈表的尾部添加元素, 尾插法''' node = Node(item) if self.is_empty(): self.__head = node else: cur = self.__head while cur.next != None: cur = cur.next cur.next = node指定位置添加元素
鏈表指定位置添加元素節點
通過pre這個游標對鏈表進行循環遍歷來找到要插入的位置, 先將node.next = pre.next再將pre.next = node, 如果恰巧是在頭部和尾部插入節點的話, 直接調用之前的add()和append()方法. 使用pre=pre.next來控制游標的移動.
使用pre來指向指定位置pos的前一個位置pos-1,初始從頭節點開始移動到指定位置.
def insert(self, pos, item): '''鏈表的指定位置添加元素''' if pos <= 0: self.add(item) elif pos > (self.length() - 1): self.append(item) else: pre = self.__head count = 0 while count < (pos-1): pre = pre.next count += 1 # 循環結束后, pre指向pos-1 的位置 node = Node(item) node.next = pre.next pre.next = node刪除節點
刪除節點
先找到指定元素, 如果第一個就是要刪除的節點, 將頭指針指向頭節點的后一個節點, 如果不是, 將刪除位置前一個節點的next指向刪除位置的后一個節點. cur = cur.next來控制移動
def remove(self, item): '''鏈表刪除節點''' cur = self.__head pre = None while cur != None: if cur.elem == item: # 先判斷當前節點是否為頭節點 # 頭節點 if cur == self.__head: self.__head = cur.next else: pre.next = cur.next # 如果使用一個游標直接就是pre.next = pre.next.next break else: pre = cur cur = cur.next查找節點是否存在
鏈表查找節點是否存在,返回True或者False. 直接對鏈表進行遍歷, 如果與給定元素比較相同就放回True, 反之返回False.
def search(self, item): '''鏈表搜索元素''' cur = self.__head count = -1 while cur != None: count += 1 if cur.elem == item: return count else: cur = cur.next return False測試
對鏈表進行相應的操作來查看鏈表是否可以完成相應的功能.
if __name__ == '__main__': ll = SingleLinkList() print (ll.is_empty()) print (ll.length()) ll.append(1) print (ll.is_empty()) print (ll.length()) ll.append(2) ll.append(3) ll.append(4) ll.append(5) ll.travel() ll.add(10) ll.travel() ll.insert(-1, 100) ll.travel() ll.insert(7,1000) ll.travel() ll.insert(2, 1111) # 100 10 1111 12345 1000 ll.travel() print (ll.search(100)) # 0 print (ll.search(10)) # 1 print (ll.search(1)) # 3 print (ll.search(1000)) # 8 ll.travel() ll.remove(10) ll.travel() ll.remove(100) ll.travel() ll.remove(1000) ll.travel()運行結果如下(建議每寫完一個功能就進行相應的測試, 避免最后運行的時候問題太多, 這里為了方便就直接一次性調試, 要不然一張一張上截圖太麻煩了.):
單鏈表功能演示運行結果
鏈表與順序表的對比
鏈表失去了順序表隨機讀取的優點,同時鏈表由于增加了結點的指針域,空間開銷比較大,但對存儲空間的使用要相對靈活。
鏈表與順序表的各種操作復雜度如下所示:
單鏈表與順序表的復雜度對比圖
注意 雖然表面看起來復雜度都是 O(n),但是鏈表和順序表在插入和刪除時進行的是完全不同的操作。鏈表的主要耗時操作是遍歷查找,刪除和插入操作本身的復雜度是O(1)。順序表查找很快,主要耗時的操作是拷貝覆蓋。因為除了目標元素在尾部的特殊情況,順序表進行插入和刪除時需要對操作點之后的所有元素進行前后移位操作,只能通過拷貝和覆蓋的方法進行。
總結
以上是生活随笔為你收集整理的node 获取表单数据 为空_数据结构与算法(python)单向链表篇的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python怎么导入图片_python怎
- 下一篇: python 读取txt文件为字典_py