python實現(xiàn)常見數(shù)據(jù)結(jié)構(gòu)

一. 二叉樹構(gòu)建以及遍歷

1.構(gòu)建結(jié)點

二叉樹的結(jié)點Node有數(shù)據(jù)域滴肿,左孩子和右孩子三部分属百。

class Node(object):
    def __init__(self,item):
        self.elem = item
        self.lchild = None
        self.rchild = None    

2.利用上面的結(jié)點構(gòu)建一個樹類

class Tree(object):
    def __init__(self):
        self.root = None

樹添加結(jié)點的方法

def add(self,item):
    """
        param: item 是傳進(jìn)來來的數(shù)據(jù),我們要實例化一個結(jié)點取接收他,但是他的位置要放在樹梢,不能亂插入
               queue 我們創(chuàng)建一個隊列來接收和彈出結(jié)點,這樣我們找到結(jié)點需要接收的位置
    """
    node = Node(item)
    if self.root is None:
        """如果根結(jié)點是None,是一顆空數(shù),我們就把node賦值給root,那么下面的while循環(huán)是不會受影響的,因為是隊列[None]的bool值是True"""
        self.root = node
        return
    #把要遍歷的結(jié)點加入queue隊列中
    queue = [self.root]
    while queue:
        #隊列的彈出要加0酥夭,與棧相仿
        cur_node = queue.pop(0)
        if cur_node.lchild is None:
            #這里有空位,插入結(jié)點
            cur_node.lchild = node
        else:
            #cur_node的做孩子放進(jìn)隊列中,下次循環(huán)左子結(jié)點
            queue.append(cur_node.lchild)
        #同理對于右邊的操作
        if cur_node.rchild is None:
            cur_node.rchild = node
        else:
            queue.append(cur_node.rchild)

廣度遍歷 —— 層序遍歷

遞歸版

def levelOrder(self,root):
    def helper(node,level):
        if not node:
            return 
        else:
            sol[level-1].append(node.val)
            if len(sol) == level: #遍歷到新層時爹耗,只有最左邊的結(jié)點使得等式成立
                sol.append([])
            helper(node.lchild,level+1)
            helper(node.rchild,level+1)
    sol = [[]]
    helper(root,1)
    return sol[:-1]

循環(huán)版

def breadth_travel(self):
        """廣度遍歷與結(jié)點的添加非常相似,廣度遍歷不用插入結(jié)點了,在循環(huán)里面的條件和添加的相仿"""
        if self.root is None:
            return 
        queue = [self.root]
 
        while queue:
            cur_node = queue.pop(0)
            # 我們打印看看結(jié)點的遍歷順序?qū)Σ粚?            print(cur_node.elem)
            if cur_node.lchild is not None:
                # 扔進(jìn)隊列循環(huán)
                queue.append(cur_node.lchild)
            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)

深度遍歷:前序奔滑,中序艾岂,后序

遞歸版

#先序遍歷 根左右
def preOrder(self,node):
    if self.root is None:
        return 
    print(node.elem)
    self.preOrder(node.lchild)
    self.preOrder(node.rchild)

#中序遍歷  左根右
def middleOrder(self,node):
    if self.root is None:
        return 
    self.preOrder(node.lchild)
    print(node.elem)
    self.preOrder(node.rchild)

#后序遍歷  左右根
def lastOrder(self,node):
    if self.root is None:
        return 
    self.preOrder(node.lchild)
    self.preOrder(node.rchild)
    print(node.elem)

循環(huán)版 —— 使用棧遍歷二叉樹

    def front(self):
        """堆棧前序遍歷"""
        if not self.root:
            return
        tmp_stack = []
        node = self.root
        while tmp_stack or node:
            while node:
                print(node.data)
                tmp_stack.append(node)
                node = node.left_child
            node = tmp_stack.pop()
            node = node.right_child

    def middle(self):
        """堆棧中序遍歷"""
        if not self.root:
            return
        tmp_stack = []
        node = self.root
        while tmp_stack or node:
            while node:
                tmp_stack.append(node)
                node = node.left_child
            node = tmp_stack.pop()
            print(node.data)
            node = node.right_child

    def last(self):
        """堆棧后序遍歷,較難"""
        if not self.root:
            return
        tmp_node = self.root
        tmp_stack = []
        while tmp_node or tmp_stack:
            while tmp_node:
                tmp_stack.append(tmp_node)
                tmp_node = tmp_node.left_child or tmp_node.right_child
            tmp_node = tmp_stack.pop()
            print(tmp_node.data)
            if tmp_stack and tmp_stack[-1].left_child is tmp_node:
                tmp_node = tmp_stack[-1].right_child
            else:
                tmp_node = None

    def lastSimpleV(self,root):
        stack = []
        sol = [] #保存打印輸出結(jié)果的列表
        curr = root
        while stack or curr:
            if curr:
                sol.append(curr.data)
                stack.append(curr.left_child)
                curr = curr.right_child
            else:
                curr = stack.pop()
        return sol[::-1]  #反向打印結(jié)果

二 鏈表的創(chuàng)建及相關(guān)操作

1.定義一個單鏈表結(jié)點類

class Node(object):
    def __init__(self,data):
        self.data = data
        self.next = None

2.方法

#判斷是否為空
def isEmpty(self):
    return (self.length ==0)

#增加一個結(jié)點,增加之后 要把鏈表長度加一
def append(self,dataOrNode):
    item = None
    if isinstance(dataOrNode,Node):
        #如果是結(jié)點的話
        item = dataOrNode
    else:
        item = Node(dataNode)
     if not self.head:  
        #如果頭結(jié)點為空的話直接插入
        self.head = item
        self.length += 1
    else:
        node = self.head
        while node.next:
            node = node.next
        node.next = item
        self.length += 1

#刪除一個結(jié)點,刪除結(jié)點之后要把鏈表長度減
def delete(self,index):
    if self.isEmpty():
        print("this chain table is empty")
        return 
    if index<0 or index>=self.length:
        print("error:out of index")
        return
#刪除第一個結(jié)點
if index==0:
        self.head = self.head.next
        self.length -= 1
        return
#prev為保存前驅(qū)結(jié)點
#node為保存當(dāng)前結(jié)點
#當(dāng)j與index相等時就朋其,相當(dāng)于找到要刪除的節(jié)點
j = 0
node = self.head
prev = self.head
while node.next and j<index:
    prev = node
    node = node.next
    j+=1
if j==index:
    prev.next = node.next
    self.length -= 1

#更新結(jié)點值
def update(self,index,data):
    if self.isEmpty() or index <0 or index>=self.length:
        return 
    j = 0
    node = self.head
    while node.next and j<index:
        node = node.next
        j += 1
    if j == index:
        node.data = data

三 圖的創(chuàng)建以及深度廣度遍歷


?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末王浴,一起剝皮案震驚了整個濱河市脆炎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌氓辣,老刑警劉巖秒裕,帶你破解...
    沈念sama閱讀 219,490評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異钞啸,居然都是意外死亡几蜻,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,581評論 3 395
  • 文/潘曉璐 我一進(jìn)店門体斩,熙熙樓的掌柜王于貴愁眉苦臉地迎上來梭稚,“玉大人,你說我怎么就攤上這事絮吵』】荆” “怎么了?”我有些...
    開封第一講書人閱讀 165,830評論 0 356
  • 文/不壞的土叔 我叫張陵蹬敲,是天一觀的道長暇昂。 經(jīng)常有香客問我,道長伴嗡,這世上最難降的妖魔是什么急波? 我笑而不...
    開封第一講書人閱讀 58,957評論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮瘪校,結(jié)果婚禮上澄暮,老公的妹妹穿的比我還像新娘。我一直安慰自己渣淤,他們只是感情好赏寇,可當(dāng)我...
    茶點故事閱讀 67,974評論 6 393
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著价认,像睡著了一般嗅定。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上用踩,一...
    開封第一講書人閱讀 51,754評論 1 307
  • 那天渠退,我揣著相機與錄音,去河邊找鬼脐彩。 笑死碎乃,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惠奸。 我是一名探鬼主播梅誓,決...
    沈念sama閱讀 40,464評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了梗掰?” 一聲冷哼從身側(cè)響起嵌言,我...
    開封第一講書人閱讀 39,357評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎及穗,沒想到半個月后摧茴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,847評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡埂陆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,995評論 3 338
  • 正文 我和宋清朗相戀三年苛白,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片焚虱。...
    茶點故事閱讀 40,137評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡购裙,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出著摔,到底是詐尸還是另有隱情缓窜,我是刑警寧澤定续,帶...
    沈念sama閱讀 35,819評論 5 346
  • 正文 年R本政府宣布谍咆,位于F島的核電站,受9級特大地震影響私股,放射性物質(zhì)發(fā)生泄漏摹察。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,482評論 3 331
  • 文/蒙蒙 一倡鲸、第九天 我趴在偏房一處隱蔽的房頂上張望供嚎。 院中可真熱鬧,春花似錦峭状、人聲如沸克滴。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,023評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劝赔。三九已至,卻和暖如春胆敞,著一層夾襖步出監(jiān)牢的瞬間着帽,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,149評論 1 272
  • 我被黑心中介騙來泰國打工移层, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留仍翰,地道東北人。 一個月前我還...
    沈念sama閱讀 48,409評論 3 373
  • 正文 我出身青樓观话,卻偏偏與公主長得像予借,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,086評論 2 355

推薦閱讀更多精彩內(nèi)容