Python帶你了解數據結構【一】

2021-12-25 Python亂燉

我們學過計算機的童鞋們都知道算法與數據結構一直是大家逃不掉的噩夢,那麼今天小編就帶大家來看看用python來解讀這些數據結構是否會變得簡單一點呢?

數據結構,顧名思義就是存放數據的結構,結構的不同會導致我們增刪改查數據的效率也大不相同,所以為了能夠高效的操作數據,我們需要了解數據結構,並且在適當的情況下使用特定的數據結構。

舉個簡單的例子,我現在期中考試的成績出來了,我需要登記大家期中考試的成績,這個時候我們需要使用什麼數據類型?

大家都知道python裡面有list和tuple這兩種數據類型。現在我們需要一份名單,並且需要在這份名單上做更新和修改處理,那對應的我們需要選擇什麼數據結構呢?因為需要做修改的操作,所以我們選擇list作為我們存儲數據的主要方式。當登記完所有的成績,我們需要把成績發放到各位同學手中,這個時候為了保證每個人的真實成績都是不可被修改的,我們又需要改變數據結構,選擇tuple類型,來確保每個同學的成績都是不可被修改的!

上面這個例子就是告訴我們,在不同的時候,我們往往需要選擇不同的數據結構來存儲對應的數據,以確保我們能夠高效的訪問或者修改數據,這也就是我們需要學習數據結構的初衷了~

首先,關於數據結構,我們主要分為兩類,線性結構和非線性結構,線性結構中的元素都是一一對應的關係,而非線性結構可能存在一對多,多對多的關係。舉個例子,一次函數:y=kx(一條直線),x和y的值都是一一對應的,這種關係就是線性結構。

但是像y=kx^2,這種結構就屬於非線性結構了,一個y對應兩個x的值。

線性結構裡面主要有數組(Array),棧(Stack),隊列(Queue),鍊表(Linked List)

非線性結構主要是:樹(Tree),圖(Graph),堆(Heap),散列表(Hash)

今天我們主要來看看線性結構。

數組(Array)

數組,將具有相同類型的若干變量有序地組織在一起的集合就是數組。在python裡面,list就是數組。

array = [1, 2, 3, 4, 5, 6, 7]

使用中括號包圍,將裡面的多個元素用逗號隔開,這就是數組了。對於數組我們如何進行它的增刪改查操作呢?

數組是一個有序的集合,所以在數組中,每個元素都有一個與之對應的索引,通過這個索引我們就能取到這個值。

print(array[0])
獲取索引為0的元素的值

關於數組的修改操作:

修改元素值
array[0] = 5
中間插入新的值
array.insert(0, 5)
尾部插入新的值
array.append(5)
刪除值
array.remove(5)

鍊表(Linked List)

說了數組就不得不說和數組相似的鍊表,鍊表的定義是不連續(這個不連續是針對於物理存儲而言),沒有順序的數據結構。是由多個節點組成的。

從下圖中我們可以看出,鍊表好像就是一個單向傳遞的過程,總是由上一個傳向下一個(這就是單鍊表),並且每個節點都是由兩部分組成,一部分存放數據,一部分指向下一個節點。這就像接力賽跑一樣,每個隊員都需要將自己的接力棒傳向下一個隊員。

(鍊表和數組的區別)

鍊表分為單鍊表,雙鍊表和循環鍊表,我們這邊以簡單常見的單鍊表為例。談談,簡單鍊表的python實現

鍊表是由多個不同的節點構成的,所以我們需要定義一個節點,一個節點主要包含兩部分,一部分是指針,指向下一組數據,另一部分是存放數據的信息。

class Node(object):

    #初始化,需要傳入節點的數據
    def __init__(self, data):
        self.data = data
        self.next = None


作為節點類,要具備一些常用的方法,獲取節點數據,獲取下個節點,更新節點的數據,更新下個節點,這些都可以定義在node類裡面。

    #返回節點的數據
    def get_data(self):
        return self.data

    #更新節點的數據
    def set_data(self, new_data):
        self.data = new_data

    #返回後繼節點
    def get_next(self):
        return self.next

    #變更後繼節點
    def set_next(self, new_next):
        self.next = new_next

定義完節點後,我們就可以來實現簡單的鍊表了。

首先來說一下鍊表的添加:添加操作,如果是插入操作,需要刪除原有的指針,將被刪除的指針重新指向新的節點,新的節點指向原來節點指向的那個節點。如果是添加在頭部,只需要將新的節點指向頭節點即可。

刪除操作,需要將被刪節點的前一個節點直接指向被刪節點的後一個節點即可。

# Reference codes:https://www.jianshu.com/p/e4000619232bclass Linked_list:

    # 初始化,頭結點為空
    def __init__(self):
        self.head = None

    # 添加節點,添加的新節點作為新的頭結點
    def add(self, data):
        new_node = Node(data)
        new_node.set_next() = self.head
        self.head = new_node

    # 包含查詢,傳入值,返回該值在鍊表中是否存在
    def search(self, data):
        checking = self.head  # 從頭結點開始查詢
        while checking != None:
            if checking.get_data() == data:  # 查找到,返回True
                return True
            checking = checking.get_next()  # 查詢下一個節點
        return False  # 遍歷到最後也未能找到,返回False

    # 刪除節點,將第一個具有傳入值的節點從鍊表中刪除
    def remove(self, data):
        checking = self.head  # 從頭結點開始查詢
        previous = None  # 記錄前一個節點,頭結點的前一個節點為None

        while checking != None:
            if checking.get_data() == data:  # 查找到,跳出查找循環
                break
            previous = checking  # 更新前一個節點
            checking = checking.get_next()  # 查詢下一個節點

        if previous == None:  # 如果頭結點便是查找的節點
            self.head = checking.get_next()
        else:  # 查找的節點不在頭節點,即,存在前驅節點
            previous.set_next(checking.get_next())


    # 判斷鍊表是否為空
    def isEmpty(self):
        return self.head == None


    # 返回鍊表長度
    def size(self):
        count = 0
        counting = self.head  # 從頭結點開始計數
        while counting != None:
            count += 1
            counting = counting.get_next()
        return count

以上我們便實現了一個簡單的鍊表。而關於雙鍊表和循環鍊表呢,與單鍊表不同的是,雙鍊表多了一個頭指針,每個節點既可以指向上個節點也可以指向下個節點。循環鍊表的特點就是最後一個節點的指針指向頭節點。

棧(Stack)

棧,也是一種線性的數據結構,他有個最經典的特徵就是FILO(先進後出原則)。

先進後出是什麼意思呢?打個比方,你現在有個羽毛球球桶,當你需要打球的時候,通常會在球桶頂端拿球,打完了放回去的時候,卻不能放在頂端,只能從底部塞入,再次去拿球的時候,只能從頂部去拿新的球,這就是這就是棧。(下圖有誤,應該是從哪放就從哪拿)

如何用python實現棧呢?我們使用python中的list來實現十分簡單。因為棧的特性,它的刪除操作只能從棧頂開始刪,所以移除的元素都是棧頂元素,添加元素也只能從棧底添加。

class Stack:
    # 初始化棧為空列表
    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, item):
        return self.items.pop()

隊列(Queue)

隊列,也是一種線性的數據結構,它和棧正好相反,它的特徵是FIFO(先進先出原則)。

先進先出的意思是:打個比方,一個n節的火車進入了隧道,最先出隧道的那節車廂肯定就是最先入隧道的那節車廂了,這就是隊列。

和上面一樣,我們也可以使用list來實現一個隊列:

class Queue:
    def __init__(self):
        self.items = []

    def enqueue(self, item):
        self.items.append(item)

    def dequeue(self):
        return self.items.pop(0)

    def empty(self):
        return self.size() == 0

    def size(self):
        return len(self.items)

python裡面也有自帶queue(隊列)這樣一個模塊,可以直接使用。(這裡我們就不提python裡面其他的隊列了,例如LifoQueue,PriorityQueue)

import queue

q = queue.Queue(3)  # 調用構造函數,初始化一個大小為3的隊列
print(q.empty())  # 判斷隊列是否為空,也就是隊列中是否有數據
#  入隊,在隊列尾增加數據, block參數,可以是True和False 意思是如果隊列已經滿了則阻塞在這裡,
# timeout 參數 是指超時時間,如果被阻塞了那最多阻塞的時間,如果時間超過了則報錯。
q.put(13, block=True, timeout=5)
print(q.full())  # 判斷隊列是否滿了,這裡我們隊列初始化的大小為3
print(q.qsize())  # 獲取隊列當前數據的個數
#  block參數的功能是 如果這個隊列為空則阻塞,
#  timeout和上面一樣,如果阻塞超過了這個時間就報錯,如果想一隻等待這就傳遞None
print(q.get(block=True, timeout=None))

#  queue模塊還提供了兩個二次封裝了的函數,
q.put_nowait(23)  # 相當於q.put(23, block=False)
q.get_nowait()  # 相當於q.get(block=False)

以上,便是線性數據結構的python版本的介紹,下期我們將聊聊:非線性的數據結構,歡迎「轉發」或者點擊「在看」支持!

「掃一掃,關注我吧」

相關焦點

  • 了解這些python數據結構,你也可以進BAT
    了解了數據結構,你就能把python代碼寫的如絲般順滑。  現如今在很多大廠面試中,面試官都會著重考察候選人對數據結構的認識程度和應用水平,為什麼呢?因為在實際工作過程中,數據結構就像代碼的地基一樣,地基不牢地動山搖。只有充分理解數據機構,才能在工作中應用的得心應手。Python中有哪些數據結構呢?
  • python高級用法,自定義數據結構,我猜你一定沒使用過
    文/IT可達鴨圖/IT可達鴨、網絡前言每個學習python的人都會對這些原生的數據結構有一定的了解,python底層給我們提供了多種多樣的原生數據結構,例如:list同樣的,原生數據結構所定義的基本方法,也是大家所熟悉的,例如:len()、str()、int()等等。當然還有,我們最最熟悉的比較操作符,例如:>=、==、<=等等。還有運算操作符、容器操作等等。魔術方法我現在告訴你,其實上面這些原生數據結構、操作符、運算符都可以自定義,而且非常簡單。
  • 必須掌握的四種python數據結構,五分鐘快速掌握
    數據結構是相互之間存在一種或多種特定關係的數據元素的集合今天要講python的四個內置數據結構:分別是列表、元組、集合和字典,每種結構數據都有自己的特點,應用於不同情況,現在你知道了四種的區別,但是可能不知道什麼時候該用哪一種數據結構,不要著急,等到具體的案例的時候,你自然會知道使用哪一種03回顧總結
  • Python基礎學習—數據結構:列表
    前面我們學習了pyth
  • 數據挖掘之Python基礎(一)基本數據類型與數據結構
    前言最近工作和研究涉及到數據挖掘和機器學習,出於歸納和總結知識的目的寫下這一系列的文章,這一系列文章將會包括Python的基本數據類型和數據結構,函數和面向對象相關的知識,然後會介紹數據挖掘和機器學習經常用到的Numpy,Pandas。也希望這一系列文章能夠幫助剛剛接觸Python或者數據挖掘和機器學習的人。
  • python系列(struct-數據結構之二進位數據結構)
    函數與結構類一組模塊級函數可用於處理結構化值以及Struct類。格式說明符從其字符串格式轉換為編譯表示形式,類似於處理正則表達式的方式。包裝和拆包Structs支持將數據打包成字符串,並使用格式說明符從字符串中解壓縮數據,格式說明符由表示數據類型和可選計數和字節順序指示符的字符組成。
  • python數據結構總結——集合
    python中,列表和元組都是序列的一種,它們的基本特徵,最大區別在於,列表是可變的,而元組則是不可變的。python中還有另外一種序列,叫做集合。python集合集合也是一種序列。它的特點是可變,但是無法通過索引操作。因為集合中的元素是無序的。當試圖通過索引進行操作時,會提示TypeError,類型錯誤。集合中的元素還是不可重複的。當嘗試向一個集合中,添加多個重複元素時,重複元素只會存在一個。
  • Python基石 | Python中的數據結構詳解
    了解Python提供的不同數據結構,包括列表、元組等介紹數據結構聽起來是一個非常直截了當的話題,但許多數據科學和分析的新手並不知道它是什麼,當我詢問這些人關於Python中不同的數據結構以及它們是如何工作的時,他們一片空白。
  • python 數據結構
    收錄於話題 #python列表Python中列表是可變的,這是它區別於字符串和元組的最重要的特點,一句話概括即:列表可以修改,而字符串和元組不能。方法描述list.append(x)把一個元素添加到列表的結尾,相當於 a[len(a):] = [x]。list.extend(L)通過添加指定列表的所有元素來擴充列表,相當於 a[len(a):] = L。
  • 新手必知的Python數據結構詳解
    數據結構屏蔽了數據存儲和操作的細節,讓程式設計師能更好的處理業務邏輯,同時擁有快速的數據存儲和獲取方式。在這篇文章中,你將了解到多種數據結構以及這些數據結構在Python中實現的方式。    通常來說,數據結構分為兩類:原始數據結構和非原始數據結構,原始數據結構是用來表示簡單的數據關係,非原始數據結構包含原始數據結構,同時,數據關係更加複雜,數據操作也更加複雜。原始數據結構    原始數據結構 - 顧名思義 - 是最原始的或基本的數據結構。
  • python數據分析專題 (7):python數據分析模塊
    也就是這些python的擴展包讓python可以做數據分析,主要包括numpy,scipy,pandas,matplotlib,scikit-learn等等諸多強大的模塊,在結合上ipython交互工具 ,以及python強大的爬蟲數據獲取能力,字符串處理能力,讓python成為完整的數據分析工具。
  • 小白學 Python(12):基礎數據結構(字典)(上)
    人生苦短,我選Python前文傳送門小白學 Python(1):開篇小白學 Python(2):基礎數據類型(上)小白學 Python(3):基礎數據類型(下)小白學 Python(4):變量基礎操作小白學 Python(5):基礎運算符(上)小白學 Python(6):基礎運算符(下)小白學 Python(7):基礎流程控制(上)小白學 Python(8):基礎流程控制(下)小白學 Python(9):基礎數據結構(列表)(上)小白學 Python(10):
  • 「對比Python學習Go」- 高級數據結構下篇
    上篇說道,Go和Python的數據結構可分為類數組和哈希結構。本篇我們來看下哈希結構相關的類型。哈希結構哈希結構又叫做散列表(hash table),它是數組的一種擴展。更多哈希知識,可參考我整理的有關散列表的筆記 數據結構與算法 - 散列表[2]。了解了上邊列出的哈希結構的基本知識後,我們來看看 Go 和 Python 的哈希結構是如何的。
  • Python內置數據結構 | 列表篇
    >本文目錄如下:  1.列表的概念  2.列表的訪問 3.列表的修改  4.列表的增加  5.列表的刪除  6.列表的其他操作                                    1 列表的概念列表是python
  • 學好Python,必須熟練掌握的幾種數據結構【文末送書】
    python提供了多種數據結構可供選擇,除了全局的列表、字典、集合和元組4個基本類型外,collections模塊提供了一些定製化的數據結構集合類數據結構,array和heapq模塊則分別提供了數組和堆數據結構,本文就這4種類型加以分別介紹。本文所指數據結構特指容器類數據結構,不包含int、str、boolean等單數據類型。
  • 史上最全的Python數據結構:列表和元組用法總結
    閱讀本文大概需要8分鐘:Python內置了很多有用的數據結構,今天我們先來介紹2大法寶,列表和元組
  • 一日一技:python中4大數據結構常用接口簡介
    具體到python中數據結構的選擇運用,雖然有很多類型可供選擇:除了基本的列表、字典、集合和元組4個基本類型外,collections模塊中提供了很多定製化的數據結構,還有專用的堆heapq和枚舉enum等。誠然,特定數據結構在某些應用場景下可能有神奇的效果,但把基礎數據類型用到極致也可堪稱是絕招。
  • 小白學 Python 數據分析(3):Pandas (二)數據結構 Series
    (1):數據分析基礎小白學 Python 數據分析(2):Pandas (一)概述引言先介紹下 Pandas 的數據結構,畢竟數據結構是萬物的基礎。Pandas 有兩種主要的數據結構:Series 和 DataFrame ,本文就先介紹第一種 Series 。
  • 搞定Python的幾個常用數據結構!
    python基本數據類型數字類型各進位的表示與轉換序列str字符串列表(list)元組(tuple)序列總結集合(set)字典(dict)轉義字符知識點總結首先需要你的電腦安裝好了數字類型 python中的數據類型==僅有int和float兩種==(沒有如short,long,double之分)具體運算中數據的類型這裡查看各種情況的數據類型運用到了python中的==type函數==print(type(1))print(type(-1
  • Python數據類型串講(上)
    CDA數據分析師 出品1、什麼是數據學習一門新的程式語言,掌握其語法的底層是我們第一步要做的事。編程的底層也就是我們常說的基礎,下面將從python的基礎中的數據類型開始入門。何為數據?像我們日常生活中的事物,可以分為固態、液態、氣態等,python語言中的數據也有其對應的「狀態」,且要求更加嚴格,不同的狀態用不同類型的數據去表示,不允許存在語法歧義。數據結構的意義:將上述五大數據類型整合到一起。但是摻到一起不是目的。目的是能夠組合成一個好的結構,方便自己或者他人進行數據存儲或者讀取。