數據結構(列表,隊列,棧,鏈表)

1.說明

1.1 概念

  簡單來說,數據結構是用來設計數據以何種方式組織並存儲在計算機中,像我們常見的列表,字典,元祖等都屬於數據結構

1.2 分類

  按照其邏輯可以分爲線性結構,樹結構,圖結構

  線性結構:數據結構中的元素存在一對一的相互關係,如列表

  樹結構:數據結構中的元素存在一對多的相互關係

  圖結構:數據結構中的元素存在多對多的相互關係

2.關於列表(數組)

  在其他語言中列表被稱爲數組(像c),在Python中被稱爲列表,這兩者之間還是存在區別的:

    列表可以可以混合存儲元素類型,像字符串,整數等,而數組不行,要求元素類型一致

    數組長度是固定的,而Python中長度不夠會開闢新的內存地址,再把原來的內容拷過來

3.關於隊列(queue)

  它屬於一種數據集合,僅允許在列表的一端進行插入,另外一端進行刪除

  特點:聯想我們排隊打飯,都是先進先出,對頭出隊,隊尾進隊

  雙向隊列:隊列的兩端都支持進隊和出隊操作

3.1 python隊列內置模塊

  基本操作:

    創建隊列:queue = deque(li)

    進隊:append

    出隊:popleft

    雙向隊列隊首進隊:appendleft

    雙向隊列隊尾進隊:pop

from collections import deque

lis = [9,5,2,7]
q = deque(lis,8)    # 最大長度是8
q.append(4)     # 從隊尾追加
q.popleft()     # 隊首出隊

# 對於雙向對列
q.appendleft(99)    # 隊首進隊
q.pop()             # 隊尾出隊

4.關於棧(stack)

  棧也是一個數據集合,只能在一端進行插入或刪除操作的列表

  特點:後進先出。聯想一摞書,我們取書只能從上取,存入也只能從上面存

利用python代碼實現一個棧

class Stack(object):
   # 初始化棧
   def __init__(self):
      self.items = []
   # 判斷棧是否爲空
   def is_empty(self):
      return self.items == []
   # 返回棧頂
   def peek(self):
      return self.items[len(self.items) - 1]
   # 返回棧大小
   def size(self):
      return len(self.items)
   # 壓棧
   def push(self, item):
      self.items.append(item)
   # 出棧
   def pop(self):
      return self.items.pop()

4.1 python棧內置模塊

  棧的基本操作:

    進棧(壓棧):push

    出棧:pop

    取棧頂:gettop(查看棧頂元素,但不取走)  li[-1]

博客參考鏈接

 5.關於鏈表

屬於一種動態數據結構,鏈表中每一個元素都是一個對象每個對象稱爲一個節點,包含有數據域key和指向下一個節點的指針next。通過各個節點之間的相互連接,最終串聯成一個鏈表

鏈表的基本元素:

  節點:每個節點有兩個部分,左邊部分稱爲值域,用來存放用戶數據;右邊部分稱爲指針域,用來存放指向下一個元素的指針。

  head:head節點永遠指向第一個節點

  tail: tail永遠指向最後一個節點

  None:鏈表中最後一個節點的指針域爲None值

鏈表和數組的區別:

  1.數組需要提前定義大小,數據小於定義長度會浪費空間,大於定義長度則無法插入。而鏈表是動態增刪數據,可以隨意增加

  2.數組適用於獲取元素的操作,直接get索引即可。鏈表對於獲取元素需要從頭一直尋找,但是適用與增刪,直接修改節點的指向即可

  3.數組從棧中分配空間,操作方便,但是自由度小,鏈表從堆中分配空間, 自由度大但申請管理比較麻煩

 節點定義:

class Node:
    def __init__(self,data=None,next=None):
        self.data = data
        self.next = next        # 保存下一個節點對象

    def __repr__(self):
        return str(self.data)

定義鏈表:

# 定義節點
node1 = Node(1)
node2 = Node(2)
node3 = Node(3)

# 將每個節點的關係表示出來
node1.next = node2
node2.next = node3

鏈表出數:

# 順序出數
def printList(node):
    while node:
        print(node)
        node = node.next

printList(node1)


# 逆序出數
def printBackward(lists):
    if lists == None: return
    printBackward(lists.next)
    print(lists)

printBackward(node1)

5.1 鏈表基本操作

鏈表翻轉(面試常見問題)

class Node:
    def __init__(self, data=None, next=None):
        self.data = data
        self.next = next  # 保存下一個節點對象

    def __repr__(self):
        return str(self.data)


# 時間消耗O(n),空間消耗O(1)
def rever(head):
    if head == None or head.next == None:  # 邊界條件
        return head

    cur = head  # 鏈表頭
    tmp = None  # 臨時變量
    newhead = None  # 翻轉鏈表表頭
    while cur:  # 存在鏈表頭
        tmp = cur.next  # tmp爲鏈表頭下一節點
        cur.next = newhead  # 此時cur.next爲None
        newhead = cur  # 把鏈表頭賦值給翻轉鏈表頭
        cur = tmp  # 把下一節點賦值給鏈表頭
    return newhead


if __name__ == '__main__':

    head = Node(1)
    a1 = Node(2)
    a2 = Node(3)
    a3 = Node(4)
    head.next = a1
    a1.next = a2
    a2.next = a3

    p = rever(head)
    while p:
        print(p.data)
        p = p.next

最終打印結果4,3,2,1

 鏈表翻轉的四種方式:鏈接

單向鏈表的詳細操作方式:鏈接

常見數據結構:參看鏈接

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章