數據結構:鏈表、隊列、二叉樹 python代碼實現

順序表

順序表兩種存儲模式*(順序和元素外置):

在這裏插入圖片描述

  1. 順序存儲模式:適用於列表中存儲的都是同一種元素。
  2. 元素外置存儲模式:適用於列表中存儲不同的元素,先開闢空間存儲每一個數據,用順序表存儲列表中每一個元素的地址。

順序表兩種存儲結構:(一體式和分離式)

在這裏插入圖片描述

  1. 區別在於,當存儲的元素超過了順序表的存儲容量時,分離式存儲結構的標頭不需要再次申請地址,只需要改變標頭中第三次元素(存儲元素的第一個地址,即200所在的地址0x23)

順序表和鏈表的區別

  1. 時間複雜度不同在這裏插入圖片描述
    2.鏈表是將零散的內存空間利用起來,但也增加了地址的存儲。
    3.如在中間刪除操作,同樣是o(n),鏈表主要工作是在查找元素,但是順序表是爲了騰空間。

單鏈表代碼實現

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

class Single_link(object):
    def __init__(self,node = None):
        self.__head = node

    def is_empty(self):
        return self.__head == None  #布爾類型

    def length(self):
        cur = self.__head # cur.next 表示的是一個存在的節點, 如果不存在就會報錯
        count = 0
        while cur!= None:
            cur = cur.next
            count += 1
        return count

    def travel(self):
        """遍歷"""
        cur = self.__head
        while cur !=None:
            print(cur.elem,end=' ')
            cur = cur.next
        print(' ')

    def append(self,item):
        """鏈表尾部添加元素"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            while cur.next != None:
                cur = cur.next
            cur.next = node
    def add(self, item):
        """鏈表頭部添加元素"""
        node = Node(item)
        node.next =self.__head
        self.__head = node

    def insert(self, pos, item):
        """鏈表指定位置添加元素"""
        if pos <= 0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            count = 0
            pro_cur = self.__head

            while count < pos-1:
                pro_cur = pro_cur.next
                count += 1
            node = Node(item)
            node.next = pro_cur.next
            pro_cur.next = node


    def remove(self, item):
            '''刪除某個數字'''
            cur = self.__head
            pre = None
            while cur != None:
                if cur.elem == item:
                    if cur == self.__head:
                        self.__head = cur.next
                    else:
                        pre.next = cur.next
                    break
                else:  # 不是這個數字,繼續往下走
                    pre = cur
                    cur = cur.next

    def rearch(self, item):
        cur = self.__head
        while cur != None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return None

if __name__ == '__main__':
    ll = Single_link()

雙鏈表代碼實現

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


class Double_link(object):
    def __init__(self,node = None):
        self.__head = node

    def is_empty(self):
        return self.__head == None  #布爾類型

    def length(self):
        cur = self.__head
        count = 1
        while cur != None:
            count += 1
            cur = cur.next
        return count

    def travel(self):

        cur = self.__head
        while cur != None:
            print(cur.elem, end=" ")
            cur = cur.next
        print('')
    def append(self,item):
        """鏈表尾部添加元素"""
        node = Node(item)
        if self.is_empty():
            self.__head = node
        else:
            cur = self.__head
            while cur.next != None:
                cur =cur.next
            cur.next = node
            node.prev = cur

    def add(self, item):
        """鏈表頭部添加元素"""
        node = Node(item)
        node.next = self.__head
        self.__head = node

    def insert(self, pos, item):
        """鏈表指定位置添加元素"""
        if pos <= 0:
            self.add(item)
        elif pos > self.length():
            self.append(item)
        else:
            cur = self.__head
            count = 0
            node = Node(item)
            while cur != None:
                if count == pos:
                    node.prev = cur.prev
                    cur.prev.next = node
                    node.next = cur
                    cur.prev = node
                    break
                else:
                    count += 1
                    cur = cur.next

    def remove(self, item):
            '''刪除某個數字'''
            cur = self.__head
            while cur != None:
                if cur.elem == item:
                    # 當刪除的爲頭結點
                    if cur == self.__head:
                        self.__head = cur.next
                        # 當頭結點不唯一時
                        if cur.next:
                            cur.next.prve = None
                    else:
                        # 當該結點不是尾部結點
                        cur.prev.next = cur.next
                        if cur.next:
                            cur.next.prve = cur.prev
                    break
                else:
                    cur = cur.next


    def rearch(self, item):
        cur = self.__head
        while cur != None:
            if cur.elem == item:
                return True
            else:
                cur = cur.next
        return None


if __name__ == '__main__':
    ll = Double_link()

棧代碼實現


class stack(object):
    def __init__(self):
        self.__list = []

    def push(self, item):
        """添加一個新的元素到棧頂"""
        self.__list.append(item)


    def pop(self):
        """彈出棧頂元素"""
        return self.__list.pop()

    def peek(self):
        if self.__list:
            return self.__list[-1]
        """返回棧頂元素"""

    def is_empty(self):
        """判空"""
        return self.__list == []

    def size(self):
        """返回棧的元素個數"""
        return len(self.__list)


if __name__ == '__main__':
    s = stack()
    s.push(1)
    s.push(2)
    s.push(3)
    print(s.size())
    print(s.peek())
    print(s.pop())
    print(s.pop())
    print(s.pop())
    print(s.peek())
    print(s.size())

隊列代碼實現

class Quene(object):
    """隊列 尾部添加 頭部刪除"""
    def __init__(self):
        self.__list = []

    def insert_queue(self, item):
        """向隊列中添加一個元素"""
        self.__list.append(item)

    def del_queue(self):
        """從隊列頭部刪除一個函數"""
        return self.__list.pop(0)


    def is_empty(self):
        """判空"""
        return self.__list == []

    def size(self):
        """返回隊列大小"""
        return  len(self.__list)
if __name__ == '__main__':

    s = Quene()
    print(s.is_empty())
    s.insert_queue(1)
    print(s.is_empty())
    s.insert_queue(2)
    s.insert_queue(3)
    print(s.size())
    print(s.del_queue())
    print(s.del_queue())
    print(s.del_queue())
    print(s.size())
    print(s.is_empty())

二分查找代碼實現

def binary_search_1(alist, item):
    """遞歸法實現二分查找"""
    n = len(alist)
    # 設置退出條件
    if n > 0:
        mid = n//2
        if alist[mid] == item:
            return True
        elif alist[mid] > item:
            return binary_search_1(alist[:mid], item)
        else:
            return binary_search_1(alist[mid+1:], item)
    return False

def binary_search_2(alist, item):
    """二分查找 非遞歸實現"""
    n = len(alist)
    start = 0
    end = n-1
    while start <= end:
        mid = (start + end) // 2
        if alist[mid] == item:
            return True
        elif alist[mid] > item:
            end = mid-1
        else:
            start = mid+1
    return False

if __name__ == '__main__':
    list = [1,2,3,4,5,6]
    print(binary_search_1(list, 6))
    print(binary_search_1(list, 1))
    print(binary_search_2(list, 6))
    print(binary_search_2(list, 1))
  

樹的概念與二叉樹代碼實現

  • 常見樹結構:滿二叉樹:滿子樹
    完全二叉樹:最後一層可以不滿,但是要靠左,子樹爲0,1都行
    平衡二叉樹:最後一層只要有子樹,就必須是兩個
    二叉排序樹:結點值爲 左<中<右
    哈夫曼樹、B樹。

  • 二叉樹特徵:
    性質1:第i層最多有2^(i-1)個結點
    性質2:深度爲K的二叉樹最多有2^(k-1)個結點
    性質3:葉結點數爲X,度爲2的結點總是爲Y,X = Y+1。
    性質4:n個結點的完全二叉樹,深度爲log2(n+1)
    性質5:完全二叉樹,從上到下,從左到右的編碼,編號爲i的結點,其左孩子必爲2i,右孩子爲2i+1;雙親爲i/2(i=1時爲根,除外)

  • 廣度優先遍歷:層次遍歷 (使用隊列來添加)

  • 深度優先遍歷:
    前序遍歷:根 左 右 (先根遍歷)
    中序遍歷:左 根 右 (中根遍歷)
    後序遍歷:左 右 根 (後根遍歷)
    代碼實現

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

class Tree(object):
    '''二叉樹'''
    def __init__(self):
        self.root = None
    def add(self, item):
        node = Node(item)
        queue = [self.root]
        if self.root == None:
            self.root = node
            return
        # 通過隊列來實現  [A B C D E ] 從左邊取判斷是否爲空 ,空就直接添加,不空的話添加到隊列右側
        while queue:# [None]的值爲True
            cur_node = queue.pop(0)
            if cur_node.lchild is None:
                cur_node.lchild = node
                return
            else:
                queue.append(cur_node.lchild)
            if cur_node.rchild is None:
                cur_node.rchild = node
                return
            else:
                queue.append(cur_node.rchild)

    def breadth_travel(self):
        '''廣度遍歷'''
        queue = [self.root]
        if self.root == None:
            return
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.item, end=' ')
            if cur_node.lchild:
                queue.append(cur_node.lchild)
            if cur_node.rchild:
                queue.append(cur_node.rchild)
        print(' ')

    def preorder(self, node):
        """前序遍歷"""
        if node is None:
            return
        print(node.item, end=' ')
        self.preorder(node.lchild)
        self.preorder(node.rchild)

    def midorder(self, node):
        """中序遍歷"""
        if node is None:
            return
        self.midorder(node.lchild)
        print(node.item, end=' ')
        self.midorder(node.rchild)

    def postorder(self, node):
        """後序遍歷"""
        if node is None:
            return
        self.postorder(node.lchild)
        self.postorder(node.rchild)
        print(node.item, end=' ')

if __name__ == '__main__':
    tree = Tree()
    for i in range(10):
        tree.add(i)
    tree.breadth_travel()
    tree.preorder(tree.root)
    print(' ')
    tree.midorder(tree.root)
    print(' ')
    tree.postorder(tree.root)





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章