第三章——基本數(shù)據(jù)結(jié)構(gòu)

0. 目標(biāo)

  • To understand the abstract data types **stack, queue, deque, and list **.
  • To be able to implement the ADT‘s stack, queue, and deque using Python lists.
  • To understand the performance of the implementations of basic linear data structures.
  • To understand prefix, infix, and postfix expression formats.
  • To use stacks to evaluate postfix expressions.
  • To use stacks to convert expressions from infix to postfix.
  • To use queues for basic timing simulations.
  • To be able to recognize problem properties where stacks, queues, and deques are appropriate data structures.
  • To be able to implement the abstract data type list as a linked list using the node and reference pattern.
  • To be able to compare the performance of our linked list implementation with Python’s list
    implementation.

1. 課程筆記

1.1 線性數(shù)據(jù)結(jié)構(gòu)——stack 堆

  1. stack特點(diǎn)1:LIFO last-in-fist-out漆诽, 最近的在Top溜腐,最老的在Base (例如一堆書(shū))榆骚。常見(jiàn)例子:瀏覽過(guò)的URL存儲(chǔ)在stack的數(shù)據(jù)結(jié)構(gòu)棠涮,點(diǎn)擊Back button可以退回到上一個(gè)谦炬。
  2. stack的實(shí)現(xiàn)
  • stack( ): 空的stack
  • push (item): 加入一個(gè)新數(shù)據(jù)在stack top,無(wú)返回
  • pop ( ): 移除一個(gè)在stack top黍析,返回item
  • peek( ): 返回top item卖怜,但對(duì)stack 沒(méi)有修改
  • is_empty( ): 返回布爾值
  • size( ): stack的大小,返回一個(gè)整數(shù)阐枣。
class Stack():  #最右邊是top
    def __init__(self):
        self.stack = []
    def is_empty(self):
        if self.stack == []:
            return True
        else:
            False
    def push(self, item):
        self.stack.append(item)
        return self.stack
    def pop(self):
        m =self.stack.pop()
        return m
    def peek(self):
        last_num = len(self.stack) - 1
        return self.stack[last_num]
    def size(self):
        num = len(self.stack)
        return num
from Stack_function import Stack  ##從相同工程下的Stack_function.py取出Stack class的定義
s = Stack()
print(s.is_empty())
print(s.push(4))
print(s.push(5))
print(s.push('dog'))
print(s.pop())
print(s.peek())
print(s.size())
  1. stack應(yīng)用一:翻轉(zhuǎn)字符串


    a20a5b41-53cd-4435-94c5-0030a377c06a.png
    def reverse(self):
        new_list = []
        i = len(self.stack) - 1
        while i >= 0:
            m = self.stack[i]
            new_list.append(m)
            i = i - 1
        return new_list
  1. stack 應(yīng)用二:檢查括號(hào)是否成對(duì)出現(xiàn):將符號(hào)放入stack中
from Stack_function import Stack

def cheek_balance(list):
    mystack = Stack() # 初始化一個(gè)stack的空間
    index = 0
    num = len(list)
    while index < num and index >= 0:
        i = list[index] #從list中取出一個(gè)需要判斷的符號(hào)
        if i == '(': #push進(jìn)stack
            mystack.push(i)
        if i == ')' and mystack.is_empty():
            return 'sorry, it is not balance'
        if i == ')':
            mystack.pop()

        index = index + 1

    if mystack.is_empty() == True:
        return 'perfect'
    else:
        return 'sorry'
  1. stack 應(yīng)用三:十進(jìn)制轉(zhuǎn)化成二進(jìn)制:將余數(shù)放入stack中
from Stack_function import Stack

def dicimal_to_binary(k):
    mystack = Stack()
    new_string = ''
    if k == 1:    #排除0马靠、1的二進(jìn)制
        return 1
    if k == 0:
        return 0
    else:
        while k != 0:
            remainder = k % 2 # 余數(shù)
            mystack.push(remainder)
            k = k // 2  #除數(shù)
    while not mystack.is_empty():
        index = str(mystack.pop())
        new_string = new_string + index   #字符串可以通過(guò)加號(hào)連接
    return new_string

print(dicimal_to_binary(20))

1.2 線性結(jié)構(gòu)——Queue 隊(duì)列

  1. 特點(diǎn): FIFO
  2. 實(shí)現(xiàn)queue的數(shù)據(jù)結(jié)構(gòu)
class Queue():
    def __init__(self):
        self.queue = []
    def enqueue(self, item):
        self.queue.insert(0, item)
    def dequeue(self):
        return self.queue.pop()
    def  is_empty(self):
        if len(self.queue) == 0:
            return True
        else:
            return False
        #return self.queue == []
    def size(self):
        return len(self.queue)
    def print_queue(self):
        return self.queue
  1. queue的應(yīng)用一:燙手的山芋(hot potato): 約瑟夫環(huán)問(wèn)題
from queue_structure import Queue

def hot_potato(List, num):
    queue = Queue() # 初始化一個(gè)排隊(duì)
    for i in List:
        queue.enqueue(i)
    print(queue.print_queue()) #放入queue,已將考慮了bill在最前面

    while queue.size() > 1: #最后只剩下一個(gè)人
        for k in range(num):  # k = 1,2,3,4,5,6,7
            name = queue.dequeue()
            queue.enqueue(name)
        queue.dequeue() #達(dá)到7次后刪除第一個(gè)

    return queue.print_queue()

Namelist = ["Bill","David","Susan","Jane","Kent","Brad"]
print (hot_potato(Namelist, 7))
  1. queue的應(yīng)用二:打印機(jī)任務(wù)建模

1.3 線性結(jié)構(gòu)——Dequeue 雙端隊(duì)列

  1. 特點(diǎn): 兩端都可以插入和輸入
  2. 實(shí)現(xiàn)dequeue
class Dequeue():
    def __init__(self):
        self.dequeue = []

    def add_front(self, item):
        self.dequeue.append(item)

    def add_back(self, item):
        self.dequeue.insert(0, item)

    def delete_front(self):
        return self.dequeue.pop()
    
    def delet_back(self):
        return self.dequeue.pop(0)
    
    def is_empty(self):
        if self.dequeue == []:
            return True
        else:
            return False

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

    def print_dequeue(self):
        print(self.dequeue)
  1. 雙端隊(duì)列的應(yīng)用:回文檢測(cè)
    ① 一個(gè)數(shù)據(jù)結(jié)構(gòu)(list)侮繁, 不可能憑空變成另一種數(shù)據(jù)結(jié)構(gòu)(dequeue)虑粥,只能通過(guò)一個(gè)一個(gè)添加的方法,將數(shù)據(jù)錄入dequeue
    ②下面的dequeue的數(shù)據(jù)結(jié)構(gòu)宪哩,沒(méi)有dequeue[0],因?yàn)闆](méi)有定義
from dequeue_structure import Dequeue

def Palindrome_check(list):
    dequeue = Dequeue()
    n = len(list)
    for i in range(n):
        dequeue.add_back(list[i]) #倒敘輸入到dequeue中
    dequeue.print_dequeue()

    while dequeue.size() > 1:
       if dequeue.delete_back() == dequeue.delete_front():
           continue
       else:
           return "False"
    return "True"

1.4 無(wú)序隊(duì)列(節(jié)點(diǎn)存儲(chǔ)的數(shù)字大小是隨機(jī)的)——鏈表(liked list)

  1. 為什么要使用鏈表第晰?
    list插入的時(shí)候耗時(shí)太長(zhǎng)(需要向后移動(dòng))
  2. 存儲(chǔ)特點(diǎn):
    ① 節(jié)點(diǎn):一個(gè)具體存放的數(shù)值&下一個(gè)節(jié)點(diǎn)的地址
    ② head = none锁孟,既是代表了每個(gè)節(jié)點(diǎn)next node
    ③ 先add的當(dāng)作old list,將最近添加的node連接到old list
  3. 構(gòu)造鏈表結(jié)構(gòu)
class Node:
    def __init__(self, initdata):
        self.data = initdata
        self.next = None

    def get_data(self):
        return self.data

    def get_next(self): #type:Node
        return self.next

    def set_data(self, new_data):
        self.data = new_data

    def set_next_node(self, new_next):
        self.next = new_next
  1. 實(shí)現(xiàn)鏈表
class UnorderList:
    def __init__(self):
        self.head = None #!! the end of structure / the entrance point

    def is_empty(self):
        return self.head == None #查看是否有head之后有node連接

    def add(self, item):
        temp = Node(item) #初始化一個(gè)節(jié)點(diǎn)
        temp.set_next_node(self.head)  #連接上end茁瘦, 或者old list node
        self.head = temp

    def print_link_list(self):
        current = self.head
        list = []
        while current != None:
            item = current.get_data()
            list.append(item)
            current = current.get_next()
        return list


    def size(self):
        current = self.head
        sum_node = 1
        while current.get_next() != None:
            sum_node = sum_node + 1
            current = current.get_next()
        return sum_node

    def search(self, item):
        current = self.head  # star at the head
        while current.get_next() != None:
            if current.get_data() == item:
                return "Find" , item
            else:
                current = current.get_next()
        return "Not find"

    def remove(self, item):
        current = self.head
        pro_node = None
        found = False
        while not found:
            if current.get_data() == item:
                found = True
            else:
                pro_node = current
                current = current.get_next()

        if pro_node == None: #第一個(gè)節(jié)點(diǎn)刪除
            self.head = current.get_next()
        else: #其他節(jié)點(diǎn)或者最后一個(gè)節(jié)點(diǎn)
            pro_node.set_next_node(current.get_next())
    
mylist = UnorderList()
print(mylist.is_empty())
mylist.add(31)
mylist.add(30)
mylist.add(29)
print(mylist.size())
print(mylist.remove(30))
print(mylist.print_link_list())
True
3
None
[29, 31]
  1. 擴(kuò)展其他的功能append, insert, index, and pop
## 在最后一個(gè)節(jié)點(diǎn)后面增加一個(gè)節(jié)點(diǎn)品抽,記錄消耗的時(shí)間

def append(self, item):
    #search最后一個(gè)點(diǎn)
    current = self.head  #current is <class '__main__.Node'>
    new_node = Node(item)
    while current.get_next() != None:
        current = current.get_next()
    else:
        current.set_next_node(Node)
        return None
import time
mylist = UnorderList()
mylist.add(31)
mylist.add(30)
mylist.add(29)
tic = time.time()
mylist.append(10)
toc = time.time()
print('time is'+ str(1000*(toc-tic))+ 'ms')
---------------------------------------------------------------------------

AttributeError                            Traceback (most recent call last)

<ipython-input-21-29193cbe3960> in <module>()
      5 mylist.add(29)
      6 tic = time.time()
----> 7 mylist.append(10)
      8 toc = time.time()
      9 print('time is'+ str(1000*(toc-tic))+ 'ms')


AttributeError: UnorderList instance has no attribute 'append'
def insert(self, item, position):
    # initialize a node
    new_node = Node(item)
    current = self.head
    print(current.get_data())
    pos = 0
    pro_node = None
    find = False
    while not find:
        if pos != position:
            pro_node = current
            current = current.get_next()
            pos += 1
        if position == 0:  # Can I improve it?
            self.head = new_node
            new_node.set_next_node(current)
            find = True
        else:
            pro_node.set_next_node(new_node)
            new_node.set_next_node(current.get_next())
            find = True
def index(self, num):
    current = self.head
    pos = 0
    Find = False
    while not Find:
        if current.get_data() == num:
            return pos
        else:
            current = current.get_next()
            pos += 1
def pop(self):
    current = self.head
    Find = False
    pro_node = None
    while not Find:
        if current.get_next() != None:
            pro_node = current
            current = current.get_next()
            print(pro_node.get_data())

        else:
            pro_node.set_next_node(None)
            Find = True
  1. 有序鏈表,例如從小到大排列
class OrderList():
    def __init__(self):
        self.head = None
    def add(self, item):
        node = Node(item)
        node.set_next_node(self.head)
        self.head = node
        
    def print_list(self):
        current = self.head
        list = []
        while current != None:
            item = current.get_data()
            list.append(item)
            current = current.get_next()
        return list
    
    def search(self, item):
        current = self.head
        while current != None:
            if current.get_data() == item:
                return 'Find it'
                
            if current.get_data() > item:
                return 'Sorry, you dont find it'
            else:
                print('serch:', current.get_data())
                current = current.get_next()
        return 'Dont find it'
    
    def add_new_node(self, item):
        current = self.head
        pro_node = None
        print(type(pro_node))
        Find = False
        new_node = Node(item)
        pos = 0
        while not Find :

            if current.get_data() >= item:
                if pos == 0:  # 在位置0加入
                    self.head = new_node
                    new_node.set_next_node(current)
                    Find = True
                
                else:  #在中間其他位置加入|
                    pro_node.set_next_node(new_node)
                    new_node.set_next_node(current)
                    Find = True
                
            else:
                pro_node = current
                print ('through:', current.get_data())
                current = current.get_next()
                pos += 1
            
            if current.get_next() == None: #最后一個(gè)節(jié)點(diǎn)加入
                current.set_next_node(new_node)
                Find = True     
                
order_list = OrderList()
order_list.add(11)
order_list.add(9)
order_list.add(6)
print('1:', order_list.print_list())
# search
print('2:', order_list.search(8))
#add
order_list.add_new_node(12)
print('3:',order_list.print_list())
('1:', [6, 9, 11])
('serch:', 6)
('2:', 'Sorry, you dont find it')
<type 'NoneType'>
('through:', 6)
('through:', 9)
('3:', [6, 9, 11, 12])
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末甜熔,一起剝皮案震驚了整個(gè)濱河市圆恤,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌腔稀,老刑警劉巖盆昙,帶你破解...
    沈念sama閱讀 219,110評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件泻云,死亡現(xiàn)場(chǎng)離奇詭異蔚叨,居然都是意外死亡裂允,警方通過(guò)查閱死者的電腦和手機(jī)近弟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,443評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)个初,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)怎披,“玉大人疲牵,你說(shuō)我怎么就攤上這事击吱。” “怎么了瘟芝?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,474評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵易桃,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我锌俱,道長(zhǎng)颈抚,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,881評(píng)論 1 295
  • 正文 為了忘掉前任嚼鹉,我火速辦了婚禮贩汉,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锚赤。我一直安慰自己匹舞,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,902評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布线脚。 她就那樣靜靜地躺著赐稽,像睡著了一般。 火紅的嫁衣襯著肌膚如雪浑侥。 梳的紋絲不亂的頭發(fā)上姊舵,一...
    開(kāi)封第一講書(shū)人閱讀 51,698評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音寓落,去河邊找鬼括丁。 笑死,一個(gè)胖子當(dāng)著我的面吹牛伶选,可吹牛的內(nèi)容都是我干的史飞。 我是一名探鬼主播,決...
    沈念sama閱讀 40,418評(píng)論 3 419
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼仰税,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼构资!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起陨簇,我...
    開(kāi)封第一講書(shū)人閱讀 39,332評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤吐绵,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后河绽,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體己单,經(jīng)...
    沈念sama閱讀 45,796評(píng)論 1 316
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,968評(píng)論 3 337
  • 正文 我和宋清朗相戀三年葵姥,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了荷鼠。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,110評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡榔幸,死狀恐怖允乐,靈堂內(nèi)的尸體忽然破棺而出矮嫉,到底是詐尸還是另有隱情,我是刑警寧澤牍疏,帶...
    沈念sama閱讀 35,792評(píng)論 5 346
  • 正文 年R本政府宣布蠢笋,位于F島的核電站,受9級(jí)特大地震影響鳞陨,放射性物質(zhì)發(fā)生泄漏昨寞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,455評(píng)論 3 331
  • 文/蒙蒙 一厦滤、第九天 我趴在偏房一處隱蔽的房頂上張望援岩。 院中可真熱鬧,春花似錦掏导、人聲如沸享怀。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,003評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)添瓷。三九已至,卻和暖如春值纱,著一層夾襖步出監(jiān)牢的瞬間鳞贷,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,130評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工虐唠, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留搀愧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,348評(píng)論 3 373
  • 正文 我出身青樓凿滤,卻偏偏與公主長(zhǎng)得像妈橄,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子翁脆,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,047評(píng)論 2 355

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

  • 1.夢(mèng)想變賣(mài)者 2.yesbuter 3.安全感自縊者 4.依賴 自由 喜歡 與愛(ài)的本質(zhì)區(qū)別 5.潛能利用者 6....
    奧黛麗黑喵閱讀 201評(píng)論 0 0
  • 今天3.8國(guó)際婦女節(jié),先祝各位女性和選擇走向女性的同胞們節(jié)日快樂(lè)鼻种! 所有人最早接觸的女人反番,應(yīng)該都是自己的母親了吧。...
    文哲chan閱讀 210評(píng)論 0 0
  • 2018年到來(lái)的第一刻鐘我給自己送了一份新年的禮物叉钥。它就是——?jiǎng)?rùn)的《五分鐘商學(xué)院》簡(jiǎn)稱“五商”罢缸。它...
    小利說(shuō)閱讀 350評(píng)論 1 3
  • 第十四章 愛(ài)情的真諦無(wú)非就是“你懂我我懂你” (一) 像一個(gè)快樂(lè)的小鳥(niǎo),連走路都覺(jué)得應(yīng)該用蹦蹦跳跳來(lái)詮釋自己的快...
    燈歆先生閱讀 161評(píng)論 0 1
  • 說(shuō)道餃子投队,做為陜西人的我打小就喜歡吃枫疆,現(xiàn)在兒子也喜歡,作為媽媽最開(kāi)心就是南方出生的小子也喜歡吃餃子敷鸦∠⑿ǎ看著他吃...
    思念ok閱讀 347評(píng)論 0 1