用Python實現的數據結構與算法:鏈表


一、概述

鏈表(linked list)是一組數據項的集合,其中每個數據項都是一個節點的一部分,每個節點還包含指向下一個節點的鏈接(參考 《算法:C語言實現》)。

根據結構的不同,鏈表可以分為單向鏈表、單向循環鏈表、雙向鏈表、雙向循環鏈表等。其中,單向鏈表和單向循環鏈表的結構如下圖所示:

鏈表類型

二、ADT

這里只考慮單向循環鏈表ADT,其他類型的鏈表ADT大同小異。單向循環鏈表ADT(抽象數據類型)一般提供以下接口:

  • SinCycLinkedlist() 創建單向循環鏈表
  • add(item) 向鏈表中插入數據項
  • remove(item) 刪除鏈表中的數據項
  • search(item) 在鏈表中查找數據項是否存在
  • empty() 判斷鏈表是否為空
  • size() 返回鏈表中數據項的個數

單向循環鏈表操作的示意圖如下:

單向循環鏈表操作

三、Python實現

Python的內建類型list底層是由C數組實現的,list在功能上更接近C++的vector(因為可以動態調整數組大小)。我們都知道,數組是連續列表,鏈表是鏈接列表,二者在概念和結構上完全不同,因此list不能用於實現鏈表。

在C/C++中,通常采用“指針+結構體”來實現鏈表;而在Python中,則可以采用“引用+類”來實現鏈表。在下面的代碼中,SinCycLinkedlist類代表單向循環鏈表,Node類代表鏈表中的一個節點:

#!/usr/bin/env python
# -*- coding: utf-8 -*-

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 SinCycLinkedlist:
    def __init__(self):
        self.head = Node(None)
        self.head.setNext(self.head)

    def add(self, item):
        temp = Node(item)
        temp.setNext(self.head.getNext())
        self.head.setNext(temp)

    def remove(self, item):
        prev = self.head
        while prev.getNext() != self.head:
            cur = prev.getNext()
            if cur.getData() == item:
                prev.setNext(cur.getNext())
            prev = prev.getNext()

    def search(self, item):
        cur = self.head.getNext()
        while cur != self.head:
            if cur.getData() == item:
                return True
            cur = cur.getNext()

        return False

    def empty(self):
        return self.head.getNext() == self.head

    def size(self):
        count = 0
        cur = self.head.getNext()
        while cur != self.head:
            count += 1
            cur = cur.getNext()

        return count

if __name__ == '__main__':
    s = SinCycLinkedlist()
    print('s.empty() == %s, s.size() == %s' % (s.empty(), s.size()))

    s.add(19)
    s.add(86)
    print('s.empty() == %s, s.size() == %s' % (s.empty(), s.size()))

    print('86 is%s in s' % ('' if s.search(86) else ' not',))
    print('4 is%s in s' % ('' if s.search(4) else ' not',))
    print('s.empty() == %s, s.size() == %s' % (s.empty(), s.size()))

    s.remove(19)
    print('s.empty() == %s, s.size() == %s' % (s.empty(), s.size()))

運行結果:

$ python sincyclinkedlist.py
s.empty() == True, s.size() == 0
s.empty() == False, s.size() == 2
86 is in s
4 is not in s
s.empty() == False, s.size() == 2
s.empty() == False, s.size() == 1


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM