1.什麼是列表(List)?
一個數據項按照相對位置存放的數據集。特別的,被稱爲“無序表(unordered list)”,其中數據項只按照存放位置來索引,如第1個、第2個…、最後一個等。
如一個考試分數的集合“54,26,93,17,77,31”,如果用無序表來表示,就是[54,26,93,17,77,31]
2.抽象數據類型:無序表List的操作
3.用鏈表實現無序表
爲了實現無序表數據結構,可以採用鏈接表的方案。
雖然列表數據結構要求保持數據項的前後相對位置,但這種前後位置的保持,並不要求數據項一次存放在連續的存儲空間。
如下圖,數據項存放位置並沒有規則,但如果在數據項之間建立鏈表指向,就可以保持其前後相對位置。第一個和最後一個數據項需要顯式標記出來,一個是隊首,一個是隊尾,後面再無數據了。
3.1 鏈表實現
3.1.1 節點Node
鏈表實現的最基本元素是節點Node。
每個節點至少要包含2個信息:數據項本身以及指向下一個節點的引用信息。next爲None的意義是沒有下一個節點了。
3.1.2 節點Node的python實現
#定義節點
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#修改下一個節點的指向引用
temp=Node(93)#創建一個數據項爲93的節點
temp.getData()
3.2 鏈表實現無序表(UnorderedList)
可以採用鏈接節點的方式構建數據集來實現無序表。
鏈表的第一個和最後一個節點最重要。如果想訪問到鏈表中的所有節點,就必須從第一個節點開始沿着鏈接遍歷下去。所以無序表必須要有對第一個節點的引用信息。
class UnorderedList:
def __init__(self):
self.head=None
mylist=UnorderedList()
print(mylist.head)
隨着數據項的加入,無序表的head始終指向鏈條中的第一個節點。
注意!!!
無序表mylist對象本身並不包含數據項(數據項在節點中),其中包含的head只是對首個節點Node的引用。
判斷空表的isEmpty()很容易實現—return self.head ==None
3.2.1 鏈表實現:add方法實現
由於無序表並沒有限定數據項之間的順序,新數據項可以加入到原表的任何位置。按照實現的性能考慮,應添加到最容易加入的位置上。
由鏈表結構可知,要訪問整條鏈上的所有數據項,都必須從表頭head開始沿着next鏈接逐個向後查找。所以添加新數據項最快捷的位置時表頭,整個鏈表的首位置。
#定義節點
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#修改下一個節點的指向引用
def add(self,item):
temp=Node(item)
temp.setNext(self.head)
self.head=temp
3.2.2 鏈表實現:size
size:從鏈條頭head開始遍歷到表尾,同時用變量累加經過的節點數。
python代碼實現
#定義節點
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#修改下一個節點的指向引用
def size(self):
current=self.head
count=0
while current != None:
count=count+1
current=current.getNext()
return count
3.2.3 鏈表實現:search
從鏈表頭head開始遍歷到表尾,同時判斷當前節點的數據項是否爲目標。
python代碼實現
#定義節點
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#修改下一個節點的指向引用
def search(self,item):
current=self.head
isOK=False
while current !=None and not isOK:
if current.getData()==item:
isOK=True
else:
current=current.getNext()
return isOK
3.2.4 鏈表實現:remove(item)方法
(1)首先找到item,這個過程跟search一樣,但在刪除節點時,需要特別的技巧
current指向的是當前匹配數據項的節點,而刪除需要把前一個節點的next指向current的下一個節點。所以,我們在search current的同時,還要維護前一個(previous)節點的引用。
(2)找到item之後,current指向item節點,previous指向前一個節點,開始執行刪除時,需要區分兩種情況:current是個首節點或者是位於鏈條中間的節點。
python代碼實現
#定義節點
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#修改下一個節點的指向引用
def remove(self,item):
previous=None
current=self.head
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())