算法(2):數據結構

數據結構:

數據結構是指相互之間存在着一種或多種關係的數據元素的集合和該集合中數據元素之間的關係組成
簡單來講, 數據結構就是設計數據以何種方式組織度存儲在計算機中
好比:列表、集合和字典等都是一種數據結構
「程序=數據結構+算法」

數據結構的分類:node

數據結構按照邏輯結構可分爲線性結構、樹結構和圖結構
線性結構:數據結構中的元素存在一對一的相互關係
樹結構:數據結構中的元素存在一對多的相互關係
圖結構:數據結構中的元素存在多對多的相互關係

另外,32位機器上,一個整數佔4個字節(4*8bit=32),一個地址也佔4個字節算法

棧:

棧(Stack)是一個數據集合,能夠理解爲只能在一端進行插入或刪除操做的列表數據結構

棧的特色:後進先出(last-in,first-out)
棧的概念:棧頂(表尾;最後一個元素),棧底(表頭;0號元素)
棧的基本操做:
    進棧(壓棧):push
    出棧:pop
    取棧頂(只查看棧頂的值,但不把棧頂刪除): gettop
使用通常的列表結構便可實現棧

棧的應用 -- 括號匹配問題:app

括號匹配問題:給一個字符串,其中包含小括號、中括號、大括號,求該字符串中的括號是否匹配
如:
    ()[]{}  # 匹配
    ([{()}])  # 匹配
    []( # 不匹配
    [(])  # 不匹配

示例代碼:spa

class BracketError(BaseException):
    def __init__(self,msg):
        super(BracketError,self).__init__()
        self.msg = msg

    def __str__(self):
        return "<%s>" %self.msg

class Stack(object):
    """實現棧的類"""
    def __init__(self):
        self.stack = []

    def push(self,ele):
        self.stack.append(ele)
    def pop(self):
        if len(self.stack) == 0:
            return None
        return self.stack.pop()
    def get_top(self):
        if len(self.stack) == 0:
            return None
        return self.stack[-1]

    def is_empty(self):
        return len(self.stack) == 0  # 返回的是一個Bool值

# 棧的應用:括號匹配問題
def bracket_match(s):
    stack = Stack()
    match_dict = {
        ")":"(",
        "]":"[",
        "}":"{"
    }
    for char in s:
        if char in ["(","[","{"]: # char 爲左括號
            stack.push(char)  # 左括號放到 棧 裏面
        else:  # char 爲右括號
            if stack.is_empty():
                raise BracketError("%s expected"%match_dict[char])
            left_bracket = stack.get_top()
            if match_dict[char] != left_bracket:
                raise BracketError("%s not match"%char)
            else:
                stack.pop()
    if not stack.is_empty():
        raise BracketError("lacking corresponding right brackets")

s = "}[]()"
bracket_match(s)

 

鏈表

1. 鏈表定義:設計

# 鏈表是由一系列節點組成的元素集合。每一個節點包含兩部分:數據域item 和 指向下一個節點的指針next。經過節點之間的相互鏈接,最終串聯成一個鏈表

示意圖:指針

示例代碼:code

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

a = Node(1)
b = Node(2)
c = Node(3)

# 把 a 和 b, c 鏈接起來
a.next = b    
b.next = c

print(a.next.item)
print(a.next.next.item)

# 打印結果:
# 2
# 3

2. 鏈表的建立和定義blog

鏈表的建立:
1) 頭插法:插到頭節點前面
2) 尾插法:插到尾節點後面

# 示例代碼:

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

def create_linkedlist_head(li):        # 經過列表進行 頭插法 建立鏈表
    head = Node(li[0])    # 利用列表的第一個元素建立鏈表頭(頭節點)
    
    for ele in li[1:]:
        node = Node(ele)    # 建立鏈表頭的上一個節點

        # 新建立的這個節點的 next 指向 頭節點,而後讓新建立的這個節點做爲頭節點
        node.next = head
        head = node

    return head  # 返回頭節點

def print_linkedlist(lk):
    # 鏈表的遍歷
    while lk:    # 節點不爲空
        print(lk.item, end=",")
        lk = lk.next
    print()

lk1 = create_linkedlist_head([1,2,3])
print_linkedlist(lk1)

# print_linkedlist(lk1) 執行結果: 
# 3,2,1,

def create_linkedlist_tail(li):        # 經過列表 尾插法 建立鏈表
    head = Node(li[0])    
    tail = head          # 此處必須經過這種賦值方式,才能讓 最初的tail 指向 head; 若是 tail = Node(li[0]) ,此時 tail 和 head 是不一樣的 Node 實例
    
    for ele in li[1:]:
        node = Node(ele)
        # 建立新節點,上一個tail的next指向這個新節點,而後讓這個新節點成爲 tail 節點
        tail.next = node
        tail = node
    return head

lk2 = create_linkedlist_tail([1,2,3,6,8])
print_linkedlist(lk2)
# 上面打印結果:
# 1,2,3,6,8,

鏈表節點的插入和刪除字符串

插入:

代碼:

p.next = curNode.next
curNode.next = p
# 上面兩步的順序不能反,即應該先把 4 和 2 鏈起來,兩把 1 和 4 鏈起來

刪除:

代碼:

curNode.next = curNode.next.next

雙鏈表

# 雙鏈表的每一個節點有兩個指針:一個指向後一個節點,另外一個指向前一個節點

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

 

示意圖:

雙鏈表的插入和刪除:

# 雙鏈表的插入
p.next = curNode.next
curNode.next.prior = p
p.prior = curNode
curNode.next = p

# 雙鏈表的刪除
p = curNode.next
curNode.next = p.next
p.next.prior = curNode
相關文章
相關標籤/搜索