1. 程式人生 > 其它 >python單鏈表

python單鏈表

單鏈表的定義

連結串列是線性表的一種,線性錶鏈式儲存結構的特點是:用一組任意的儲存單元儲存線性表的資料元素(這組儲存的單元可以是連續的,也可以是不連續的)。

為了清楚地表示單鏈表,我們還要引入節點的概念

節點的定義

為了表示連結串列中每一個數據元素a(i)與其直接後繼資料元素a(i+1)之間的邏輯關係,對於資料a(i)來說,除了儲存其本身的資訊之外還需要儲存一個指向其直接後繼的資訊。這兩部分組成資料元素a(i)的儲存映像,稱為節點。節點有兩個域,一個是儲存資訊的資料域,一個是儲存下一個節點位置的指標域。指標域中儲存的資訊稱作指標或鏈。

有了節點這個概念,我們就可以用python中的類來實現,節點的兩個域我們可以實列的屬性表示,通過例項化這個類就可以生成節點。

節點的實現:

class Node():
    def __init__(self, dataval=None):
        self.dataval = dataval  # 資料域,生成節點需要具體內容
        self.nextval = None		# 指標域

n個節點鏈結成一個連結串列。如果每個節點只包含一個指標域,那麼這個連結串列就是線性連結串列又稱單鏈表


我們一般將連結串列畫成用箭頭相連結的節點序列

為了處理方便,我們一般在單鏈表的第一個節點(首元節點)之前再加一個節點,稱為頭節點,頭節點的資料域一般不儲存內容,或者存與整個連結串列相關的資訊,比如連結串列的長度之類的,頭節點的指標域指向首元節點。

同時還要引入一個概念:頭指標,頭指標指向列表開始的位置,如果有頭節點就指向頭節點,如果沒有頭節點就指向首元節點。

再加一個頭節點是為了連結串列處理起來更加方便,這樣就不必對元首節點做特俗處理,而且即便連結串列為空,頭指標的指向也不為空。


### 程式碼實現

在python中我們一般用類和例項來實現連結串列,下面是python程式碼:

# 節點
class Node():
    def __init__(self, dataval=None):
        self.dataval = dataval  # 資料域
        self.nextval = None		# 指標域
# 連結串列
class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
        
list1 = Slinkedlist()  # 生成連結串列
list1.headval = Node()  # 設定一個頭節點,頭指標指向頭節點
e1 = Node("Mon")  #生成節點
e2 = Node("Tus")
e3 = Node("Wed")
# 再將各個節點連起來
list1.headval.nextval = e1  # 將頭節點的指標域指向首元節點
e1.nextval = e2  # 下面一次按順序連起來
e2.nextval = e3

實現了連結串列,接下來就是實現連結串列的方法和屬性

1.列印連結串列,思路就是從首節點開始,通過節點指標域不斷跳轉到下一個,直到節點域為空為止

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
    def printlist(self):  # 遍歷連結串列
        printval = self.headval.nextval  # 這裡是從元首節點開始
        while printval:
            print(printval.dataval)  # 列印內容
            printval = printval.nextval

2.求連結串列長度,思路差不多,加一個計數器就行了

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
    def __len__(self):  # 求連結串列的長度
        lenval = self.headval.nextval
        num = 0
        while lenval:
            num += 1
            lenval = lenval.nextval
        self.headval.dataval = num  # 頭節點儲存連結串列的長度
        return num

3.通過下標取值,這裡依賴前面的求長度的方法來判斷輸入下標的合法性

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
    def get(self, index, k=0):  # 取值操作
        nm = -1  # 從-1開始表示從頭節點開始,但是一般來說輸入的下標是從0開始的
        lenth = self.__len__()  # 先求出長度判斷是否越界
        if index > lenth - 1 or index < -1:
            raise "連結串列下標越界"
        node = self.headval  # 定義第一個值,從頭節點開始找
        while nm < index:
            node = node.nextval
            nm += 1
        if k == 0:
            return node.dataval
        else:
            return node

4.通過值求下標,我們規定,頭節點的下標為-1,首元節點的下標為0,後面依次遞增

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
        
    def index(self, data):  # 通過值拿到下標
        nm = 0
        node = self.headval.nextval
        while node:
            if node.dataval == data:
                return nm
            else:
                nm += 1
                node = node.nextval
        else:
            return None

5.插入操作,連結串列的插入操作和順序表不同,連結串列的插入不需要移位,只需要將要插入的位置的前一個節點的指標域改為指向新的節點,同時新加入的節點的指標域要指向後面的節點。因為有頭節點,所以我們不需要對首元節點特殊處理。

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
 def insert(self, index, value):  # 插值操作
        newnode = value  # 獲取新的節點
        ahead = self.get(index - 1, k=1)  # 獲取要插入位置前面的節點
        newnode.nextval = ahead.nextval
        ahead.nextval = newnode

6.刪除操作,同插入操作類似,這裡我們將通過下標刪除和通過值刪除合在一起

class Slinkedlist():
    def __init__(self):
        self.headval = None  # 初始化頭指標
        
    def remove(self, obj):
        if type(obj) == int:
            if obj < -1:
                raise "輸入的值不合法"
            data = self.get(obj,k=1)
            ahead = self.get(obj - 1,k=1)
            ahead.nextval = data.nextval
        else:
            index = self.index(obj)
            data = self.get(index,k=1)
            ahead = self.get(index -1,k=1)
            ahead.nextval = data.nextval

好了,python單鏈表基本就這些了。