不管是任何程序員,不管是算法,仍是其餘,都須要掌握必定的數據結構。本文以最優雅的方式,基於Python,完成算法,不要問,背下來就好。代碼量更少,更好背。html
源碼:github.com/SpikeKingnode
第2篇 棧與隊列:括號匹配(棧)、二進制轉換(棧)、燙手的山芋(隊列)、迴文(雙端隊列)、反轉鏈表(鏈表);python
括號匹配,判斷字符串中括號是否匹配。當爲左括號時入棧,爲右括號時出棧,最後,判斷棧是否爲空,爲空則括號匹配,不然不匹配。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()
複製代碼
將二進制數除以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))
複製代碼
點名,點到誰,誰出圈,循環使用隊列,最後一個出隊。算法共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()
複製代碼
雙端隊列,隊首和隊尾的輸出是否相等。算法共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()
複製代碼
鏈表反轉,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