[筆記]python資料結構之線性表:linkedlist鏈表,stack棧,queue隊列

來源:互聯網
上載者:User

標籤:

python資料結構之線性表
python內建了很多進階資料結構,list,dict,tuple,string,set等,在使用的時候十分舒心。但是,如果從一個初學者的角度利用python學習資料結構時,這些進階的資料結構可能給我們以迷惑。比如,使用list實現queue的時候,入隊操作append()時間複雜度可以認為是O(1),但是,出隊操作pop(0)的時間複雜度就是O(n)。如果是想利用python學學資料結構的話,我覺得還是自己實現一遍基本的資料結構為好。
1.鏈表在這裡,我想使用類似於c語言鏈式儲存的形式,藉助於class,分別構成無序鏈表以及有序鏈表。我們先看看鏈表節點的定義:
class ListNode(object):    def __init__(self, data):        self.data = data        self.next = None    def getData(self):        return self.data    def setData(self, newData):        self.data = newData    def getNext(self):        return self.next    def setNext(self, nextNode):        self.next = nextNode
利用鏈表節點,組成無序鏈表類:
class UnorderedList(object):    def __init__(self):        self.head = None    def getHead(self):        return self.head    def isEmpty(self):        return self.head is None    def add(self, item):        node = ListNode(item)        node.next = self.head        self.head = node   # the head is the most recently added node    def size(self):        current = self.head        count = 0        while current is not None:            count += 1            current = current.getNext()        return count    def search(self, item):        current = self.head        found = False        while current is not None and not found:            if current.getData() == item:                found = True            else:                current = current.getNext()        return found    def append(self, item):        node = ListNode(item)        if self.isEmpty():            self.head = node        else:            current = self.head            while current.getNext() is not None:                current = current.getNext()            current.setNext(node)    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 is None:            self.head = current.getNext()        else:            previous.setNext(current.getNext())
在上面的鏈表中,每次添加元素都直接添加在鏈表頭部,add()的時間複雜度為O(1),而append()操作在隊尾,其時間複雜度為O(n)。有沒有前後加入操作的時間複雜度都為O(1)的鏈表呢,當然是有的:
class UnorderedList(object):    def __init__(self):        self.head = None        self.tail = None    def getHead(self):        return self.head    def isEmpty(self):        return self.head is None and self.tail is None    def add(self, item):        node = ListNode(item)        if self.isEmpty():            self.head = self.tail = node        else:            node.next = self.head            self.head = node   # the head is the most recently added node    def size(self):        current = self.head        count = 0        while current is not None:            count += 1            current = current.getNext()        return count    def search(self, item):        current = self.head        found = False        while current is not None and not found:            if current.getData() == item:                found = True            else:                current = current.getNext()        return found    def append(self, item):        node = ListNode(item)        self.tail.setNext(node)        self.tail = node    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 current.getNext() is None:            self.tail = previous        if previous is None:            self.head = current.getNext()        else:            previous.setNext(current.getNext())
對無序鏈表類加入一個屬性,引用鏈表末尾節點,即可。做出了這樣的改變,在add和remove操作也應作出相應變化。下面再看看有序鏈表。有序鏈表在插入節點的時候便尋找適合節點的位置。
class OrderedList(object):    def __init__(self):        self.head = None    def isEmpty(self):        return self.head is None    def search(self, item):        stop = False        found = False        current = self.head        while current is not None and not found and not stop:            if current.getData() > item:                stop = True            elif current.getData() == item:                found = True            else:                current = current.getNext()        return found    def add(self, item):        previous = None        current = self.head        stop = False        while current is not None and not stop:            if current.getData() >item:                stop = True            else:                previous = current                current = current.getNext()        node = ListNode(item)        if previous is None:            node.getNext(current)            self.head = node        else:            previous.setNext(node)            node.setNext(current)
2.棧stack對於棧來說,python內建的列表已經可以滿足棧的要求。入棧操作為append(),出棧操作為pop()。它們的時間複雜度都為O(1).
class Stack(object):    def __init__(self):        self._items = []    def is_empty(self):        return self._items == []    def push(self, item):        self._items.append(item)    def pop(self):        return self._items.pop()    def peek(self):        return self._items[-1]
當然了,我們也可以自己實現鏈棧,跟鏈表的實作類別似。
class StackNode(object):    """docstring for StackNode"""    def __init__(self, value):        self.value = value        self.next = Noneclass Stack(object):    """docstring for Stack"""    def __init__(self, top=None):        self.top = top        def get_top(self):        return self.top    def is_empty(self):        return self.top is None    def push(self, val):        if self.is_empty():            self.top = StackNode(val)            return        else:            node = StackNode(val)            node.next = self.top.next            self.top = node            return    def pop(self):        if self.is_empty():            print("Stack is Empty, cannot pop anymore.\n")            return        node = self.top        self.top = self.top.next        return node
3.隊列queue隊列如果利用鏈表實現的話會,出現文章開頭提及的問題。所以隊列可以用鏈表實現。
class QueueNode(object):    def __init__(self, value):        self.value = value        self.next = Noneclass Queue(object):    def __init__(self):        self.front = None        self.rear = None    def is_empty(self):        return self.front is None and self.rear is None    def enqueue(self, num):        node = QueueNode(num)        if self.is_empty():            self.front = node            self.rear = node        else:            self.rear.next = node            self.rear = node    def dequeue(self):        if self.front is self.rear:            node = self.front            self.front = None            self.rear = None            return node.value        else:            node = self.front            self.front = node.next            return node.value
在python的庫中,比如collections以及Queue中都有deque模組。deque模組顧名思義,可以做雙端隊列。所以,deque模組也可以做隊列,和棧。dq = deque([1,2,3,4,5,6,7,8,9])dq.pop() # pop 9 dq.popleft() #pop 1dq.apend(9) # append 9dq.appendleft(1) #insert 1 in index 0在多線程,多進程編程時,經常使用Queue模組的Queue類。其實:假設q = Queue.Queue() 那麼 q.queue就是一個deque。這個以後再談。







[筆記]python資料結構之線性表:linkedlist鏈表,stack棧,queue隊列

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.