python有序列表无序列表区别_用Python链表实现有序表与无序表
用Python鏈表實現有序表與無序表
《數據結構與算法》MOOC(北大地空)課堂筆記
2020.4
by dlnb526
啥是鏈表
鏈表,顧名思義,顧名思義,鏈表像鎖鏈一樣,由一節節節點連在一起,組成一條數據鏈。
為什么要使用鏈表?
在之前用了python中的列表(list)來實現各種數據結構,然而有的語言可能并沒有提供像python的列表一樣強大的功能,我們必須要自己實現列表。
無序列表
概述
列表可以看作是一個無序的列表。
無序,也就是說它里面的元素沒有一定的順序,比如這樣一個列表:
a = [1,2,'ads',54,32]
這里面的每個元素沒有按照一定的規則排序,所以就叫無序。
無序列表應該有以下的方法
list() 創建一個新的空列表。它不需要參數,而返回一個空列表。
add(item) 將新項添加到列表,沒有返回值。假設元素不在列表中。
remove(item) 從列表中刪除元素。需要一個參數,并會修改列表。此處假設元素在列表中。
search(item) 搜索列表中的元素。需要一個參數,并返回一個布爾值。
isEmpty() 判斷列表是否為空。不需要參數,并返回一個布爾值。
size() 返回列表的元素數。不需要參數,并返回一個整數。
append(item) 在列表末端添加一個新的元素。它需要一個參數,沒有返回值。假設該項目不在列表中。
index(item) 返回元素在列表中的位置。它需要一個參數,并返回位置索引值。
此處假設該元素原本在列表中。
insert(pos,item) 在指定的位置添加一個新元素。它需要兩個參數,沒有返回值。假設該元素在列表中并不存在,并且列表有足夠的長度滿足參數提供的索引需要。
pop() 從列表末端移除一個元素并返回它。它不需要參數,返回一個元素。假設列表至少有一個元素。
pop(pos) 從指定的位置移除列表元素并返回它。它需要一個位置參數,并返回一個元素。假設該元素在列表中。
節點
為了實現無序列表,我們采用鏈表的方式。
鏈表最基本的元素是節點。
每個節點對象必須持有至少兩條信息。
首先,節點必須包含列表元素本身。我們將這稱為該節點的“數據區”(data field)。
此外,每個節點必須保持到下個節點的引用。
如果沒有下一個節點,那我們就記錄為None
class Node:#節點這個類~
def __init__(self,initdata):
self.data = initdata
self.next = None#初始化的時候頭節點后面沒有節點了
def getData(self):
return self.data #節點可以獲取自身數據
def getNext(self):
return self.next #節點可以獲取指向的下一個節點
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):#節點可以對下一個節點進行更新
self.next = newnext
上面我們就把一個節點建立起來了,那如何把節點連接起來呢。
無序表的鏈表實現
操作舉例
1. 添加數據項add
通過之前的方式建立了一個節點,如果初始化它我們知道他是一個在開頭的節點,后面是None.由于無序表是從表頭開始逐個向后查找,新數據所以插入到表頭是我們的最佳選擇。
def add(self,item):
temp = Node(item) #新的要插入的數據初始化為一個節點
temp.setNext(self.head)#但當前節點的下一個指向為之前鏈表的頭部
self.head = temp#把插入的節點設為新鏈表的頭部
2. size()的實現 和 search()的實現
def size(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self,item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
沒什么可說的,設置一個計數器,然后遍歷元素。
3. remove(item)實現
我們需要先用類似search的方法找到元素,然后它指向的后一個元素和前一個元素怎么連在一起呢?
這時就需要維護前一個節點的引用。
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current#不斷地往后找,然后把當前的節點記作前一個結點,這樣在找到后就可以對前一個結點進行操作。
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
好了那下面我們來看無序表的完整實現
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
class UnorderedList:
def __init__(self):
self.head = None
def isEmpty(self):
return self.head == None
def add(self,item):
temp = Node(item)
temp.setNext(self.head)
self.head = temp
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def search(self,item):
current = self.head
found = False
while current != None and not found:
if current.getData() == item:
found = True
else:
current = current.getNext()
return found
def remove(self,item):
current = self.head
previous = None
found = False
while not found:
if current.getData() == item:
found = True
else:
previous = current
current = current.getNext()
if previous == None:
self.head = current.getNext()
else:
previous.setNext(current.getNext())
mylist = UnorderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.length())
print(mylist.search(93))
print(mylist.search(100))
mylist.add(100)
print(mylist.search(100))
print(mylist.length())
mylist.remove(54)
print(mylist.length())
mylist.remove(93)
print(mylist.length())
mylist.remove(31)
print(mylist.length())
print(mylist.search(93))
有序鏈表
概述
之前無序鏈表時我們就能推測出有序的意思,也就是排列過大小的唄~
有序表依據數據項的可比性質(如整數大小,字母表前后)來決定數據項在列表中的位置。
比如下面我們要實現越小的越靠近列表頭的操作。
有序表中的操作:
OrderedList():創建一個新的空有序列表。它返回一個空有序列表并且不需要傳遞任何參數。
add(item):在保持原有順序的情況下向列表中添加一個新的元素,新的元素作為參數傳遞進函數而函數無返回值。假設列表中原先并不存在這個元素。
remove(item):從列表中刪除某個元素。欲刪除的元素作為參數,并且會修改原列表。假設原列表
中存在欲刪除的元素。
search(item):在列表中搜索某個元素,被搜索元素作為參數,返回一個布爾值。
isEmpty():測試列表是否為空,不需要輸入參數并且其返回一個布爾值。
size():返回列表中元素的數量。不需要參數,返回一個整數。
index(item):返回元素在列表中的位置。需要被搜索的元素作為參數輸入,返回此元素的索引值。假設這個元素在列表中。
pop():刪除并返回列表中的最后一項。不需要參數,返回刪除的元素。假設列表中至少有一個元素。
pop(pos):刪除并返回索引 pos 指定項。需要被刪除元素的索引值作為參數,并且返回這個元素。假設該元素在列表中。
有序鏈表的實現
其實大部分操作都和無序表相同
search()方法
在無序表中如果不存在,搜索的時候會遍歷整個表。
但是在有序表中,因為有順序,一旦當前節點大于要查找的數據,就直接宣判死刑可以返回False了。
def search(self,item):
current = self.head
found = False
stop = False# 加入了一個stop可以直接停住
while current != None and not found and not stop:#這里有三個條件
if current.getData() == item:
found = True
else:
if current.getData() > item:
stop = True
else:
current = current.getNext()
return found
add()方法
和無序表相比,改動最大的方法是 add。回想一下在無序列表中的 add 方法,只需要在原列表頭加一個新的節點。然而在有序表里我們要找到大小合適的位置才行。
所以我們還是要定位一個previous(前一個元素)。
def add(self,item):
current = self.head
previous = None
stop = False
while current != None and not stop:
if current.getData() > item:
stop = True
else:
previous = current
current = current.getNext()
temp = Node(item)
if previous == None:
temp.setNext(self.head)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)
有序表的完整實現如下:
class Node:
def __init__(self,initdata):
self.data = initdata
self.next = None
def getData(self):
return self.data
def getNext(self):
return self.next
def setData(self,newdata):
self.data = newdata
def setNext(self,newnext):
self.next = newnext
class OrderedList:
def __init__(self):
self.head = None
def search(self,item):
current = self.head
found = False
stop = False
while current != None and not found and not stop:
if current.getData() == item:
found = True
else:
if current.getData() > item:
stop = True
else:
current = current.getNext()
return found
def add(self,item):
current = self.head
previous = None
stop = False
while current != None and not stop:
if current.getData() > item:
stop = True
else:
previous = current
current = current.getNext()
temp = Node(item)
if previous == None:
temp.setNext(self.head)
self.head = temp
else:
temp.setNext(current)
previous.setNext(temp)
def isEmpty(self):
return self.head == None
def length(self):
current = self.head
count = 0
while current != None:
count = count + 1
current = current.getNext()
return count
def traverse(self):
current = self.head
while current != None:
print(current.getData())
current = current.getNext()
mylist = OrderedList()
mylist.add(31)
mylist.add(77)
mylist.add(17)
mylist.add(93)
mylist.add(26)
mylist.add(54)
print(mylist.length())
print(mylist.search(93))
print(mylist.search(100))
mylist.traverse()
總結分析
當分析鏈表方法的復雜度時,我們應該考慮它們是否需要遍歷鏈表。考慮一個有 n 個節點的鏈表,isEmpty 方法復雜度是 O(1),因為它只需要檢查鏈表的頭指針是否為 None。對于方法 size,則總需要 n 個步驟,因為除了遍歷整個鏈表以外,沒有辦法知道鏈表的節點數。因此,size 方法的復雜度是 O(n)。無序列表的 add 方法的復雜度是 O(1),因為我們永遠只需要在鏈表的頭部簡單地添加一個新的節點。但是,search、remove 和在有序列表中的 add 方法,需要遍歷。盡管在平均情況下,它們可能只需要遍歷一半的節點,但這些方法的復雜度都是 O(n),因為在最糟糕的情況下需要遍歷整個鏈表。
參考資料:MOOC配套教材及代碼
《Python數據結構與算法分析》 第2版
總結
以上是生活随笔為你收集整理的python有序列表无序列表区别_用Python链表实现有序表与无序表的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql 导入3亿数据
- 下一篇: 九个角度分析对比 Android、iOS