程序員必須掌握的數據結構 2

不管是任何程序員,不管是算法,仍是其餘,都須要掌握必定的數據結構。本文以最優雅的方式,基於Python,完成算法,不要問,背下來就好。代碼量更少,更好背。html

源碼:github.com/SpikeKingnode

第2篇 棧與隊列:括號匹配(棧)、二進制轉換(棧)、燙手的山芋(隊列)、迴文(雙端隊列)、反轉鏈表(鏈表);python


1. 括號匹配

括號匹配,判斷字符串中括號是否匹配。當爲左括號時入棧,爲右括號時出棧,最後,判斷棧是否爲空,爲空則括號匹配,不然不匹配。Python的list就能夠實現的功能。算法共14行。git

def par_checker(symbol_str):
    """ 括號匹配,list包含棧的功能 append是添加,pop是刪除 https://docs.python.org/2/tutorial/datastructures.html 14行 :param symbol_str: 符號字符串 :return: 是否 """
    s = list()  # python的list能夠實現stack功能
    idx = 0
    while idx < len(symbol_str):
        symbol = symbol_str[idx]
        if symbol == '(':
            s.append(symbol)
        elif symbol == ')':
            s.pop()
        idx += 1
    if not s:
        return True
    else:
        return False


def test_of_par_checker():
    print(par_checker('(())'))
    print(par_checker('((()'))
    print(par_checker('(a)()((()))'))


if __name__ == '__main__':
    test_of_par_checker()
複製代碼

2. 二進制轉換

將二進制數除以base,輸入隊列中,再倒序輸出,剛好是的功能。將數字添加至字符串中,便可。算法共11行。程序員

def base_converter(num, base):
    """ 將二進制轉換爲其餘進制 :param num: 數字 :param base: 基數 :return: 數字的字符串 """
    digs = '0123456789ABCDEF'  # 支持16位
    base_stack = list()

    while num > 0:
        rem = num % base
        base_stack.append(rem)
        num //= base  # 遞減一直到0

    res_str = ''  # 轉換爲str
    while base_stack:
        res_str += digs[base_stack.pop()]

    return res_str


if __name__ == '__main__':
    print(base_converter(25, 2))
    print(base_converter(25, 16))
複製代碼

3. 燙手的山芋

點名,點到誰,誰出圈,循環使用隊列,最後一個出隊。算法共10行。github

from queue import Queue


def hot_potato(name_list, num):
    """ 燙手的山芋,循環去除 :param name_list: 名字列表 :param num: 循環數 :return: 最後剩下的人 """
    q = Queue()

    for name in name_list:
        q.put(name)

    while q.qsize() > 1:
        for i in range(num - 1):  # 每次都死一個循環,最後一個死亡
            live = q.get()
            q.put(live)
        dead = q.get()  # 輸出死亡
        print('Dead: {}'.format(dead))

    return q.get()


def test_of_hot_potato():
    name_list = ['Bill', 'David', 'Susan', 'Jane', 'Kent', 'Brad']
    num = 3
    print(hot_potato(name_list, num))


if __name__ == '__main__':
    test_of_hot_potato()
複製代碼

4. 迴文

雙端隊列,隊首和隊尾的輸出是否相等。算法共12行。算法

from collections import deque


def pal_checker(a_str):
    """ 迴文,雙端隊列 :param a_str: 輸入字符串 :return: 是否迴文 """
    q_char = deque()

    for ch in a_str:
        q_char.append(ch)

    equal = True

    # while的終止條件長度或者Bool
    while len(q_char) > 1:
        first = q_char.pop()
        last = q_char.popleft()
        if first != last:
            equal = False
            break

    return equal


def test_of_pal_checker():
    print(pal_checker('lsdkjfskf'))
    print(pal_checker('radar'))


if __name__ == '__main__':
    test_of_pal_checker()
複製代碼

5. 鏈表反轉

鏈表反轉,prev_node保留頭結點,臨時變量next_node,保留當前結點以後的結點。算法共8行。數據結構

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


def reverse_list(node_head):
    """ 鏈表逆序,交換鏈表 :param node_head: 鏈表頭 :return: 新的鏈表的頭結點 """
    prev_node = None

    while node_head:
        next_node = node_head.next_node
        node_head.next_node = prev_node
        prev_node = node_head
        node_head = next_node

    return prev_node


def init_list():
    n1 = Node(1)
    n2 = Node(2)
    n3 = Node(3)
    n4 = Node(4)
    n5 = Node(5)
    n1.next_node = n2
    n2.next_node = n3
    n3.next_node = n4
    n4.next_node = n5
    return n1


def show_list(node_head):
    head = node_head
    while head:
        print(head.data, end=' ')
        head = head.next_node


def test_of_reverse_list():
    head_node = init_list()
    show_list(head_node)
    print()
    head_node = reverse_list(head_node)
    show_list(head_node)


if __name__ == '__main__':
    test_of_reverse_list()
複製代碼

OK, that's all! Enjoy it!app

相關文章
相關標籤/搜索