Python對數據結構的實現

1.數據結構:線性表和鏈表、堆棧和隊列、樹和二叉樹、圖、字典和集合、B樹、哈希表

鏈表

1)含義:鏈表(Linked list)是一種常見的基礎數據結構,是一種線性表,但是並不會按線性的順序存儲數據,而是在每一個節點裏存到下一個節點的指針(Pointer)。由於不必須按順序存儲,鏈表在插入的時候可以達到O(1)的複雜度,比另一種線性表順序錶快得多,但是查找一個節點或者訪問特定編號的節點則需要O(n)的時間,而順序表相應的時間複雜度分別是O(logn)和O(1)

2)特點:使用鏈表結構可以克服數組鏈表需要預先知道數據大小的缺點,鏈表結構可以充分利用計算機內存空間,實現靈活的內存動態管理。但是鏈表失去了數組隨機讀取的優點,同時鏈表由於增加了結點的指針域,空間開銷比較大

3)操作:

  • is_empty() 鏈表是否爲空
  • length() 鏈表長度
  • travel() 遍歷鏈表
  • add(item) 鏈表頭部添加
  • append(item) 鏈表尾部添加
  • insert(pos, item) 指定位置添加
  • remove(item) 刪除節點
  • search(item) 查找節點是否存在
# -*- coding: utf-8 -*-

class Node(object):
    """雙向鏈表節點"""
    def __init__(self, item):
        self.item = item
        self.next = None
        self.prev = None

class DLinkList(object):
    """雙向鏈表"""
    def __init__(self):
        self._head = None

    def is_empty(self):
        """判斷鏈表是否爲空"""
        return self._head == None

    def length(self):
        """返回鏈表的長度"""
        cur = self._head
        count = 0
        while cur != None:
            count += 1
            cur = cur.next
        return count

    def travel(self):
        """遍歷鏈表"""
        cur = self._head
        while cur != None:
            print cur.item
            cur = cur.next

    def add(self, item):
        """頭部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空鏈表,將_head指向node
            self._head = node
        else:
            # 將node的next指向_head的頭節點
            node.next = self._head
            # 將_head的頭節點的prev指向node
            self._head.prev = node
            # 將_head 指向node
            self._head = node

    def append(self, item):
        """尾部插入元素"""
        node = Node(item)
        if self.is_empty():
            # 如果是空鏈表,將_head指向node
            self._head = node
        else:
            # 移動到鏈表尾部
            cur = self._head
            while cur.next != None:
                cur = cur.next
            # 將尾節點cur的next指向node
            cur.next = node
            # 將node的prev指向cur
            node.prev = cur

    def search(self, item):
        """查找元素是否存在"""
        cur = self._head
        while cur != None:
            if cur.item == item:
                return True
            cur = cur.next
        return False

    def insert(self, pos, item):
        """在指定位置添加節點"""
        if pos <= 0:
            self.add(item)
        elif pos > (self.length()-1):
            self.append(item)
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 移動到指定位置的前一個位置
            while count < (pos-1):
                count += 1
                cur = cur.next
            # 將node的prev指向cur
            node.prev = cur
            # 將node的next指向cur的下一個節點
            node.next = cur.next
            # 將cur的下一個節點的prev指向node
            cur.next.prev = node
            # 將cur的next指向node
            cur.next = node

    def remove(self, item):
        """刪除元素"""
        if self.is_empty():
            return
        else:
            cur = self._head
            if cur.item == item:
                # 如果首節點的元素即是要刪除的元素
                if cur.next == None:
                    # 如果鏈表只有這一個節點
                    self._head = None
                else:
                    # 將第二個節點的prev設置爲None
                    cur.next.prev = None
                    # 將_head指向第二個節點
                    self._head = cur.next
                return
            while cur != None:
                if cur.item == item:
                    # 將cur的前一個節點的next指向cur的後一個節點
                    cur.prev.next = cur.next
                    # 將cur的後一個節點的prev指向cur的前一個節點
                    cur.next.prev = cur.prev
                    break
                cur = cur.next

ll = DLinkList()
ll.add(1)
ll.add(2)
ll.append(3)
ll.insert(2, 4)
ll.insert(4, 5)
ll.insert(0, 6)
print '----------------1-----------------'
print "length:",ll.length()
print '----------------2-----------------'
ll.travel()
print '----------------3-----------------'
print ll.search(3)
print ll.search(4)
print '----------------4-----------------'
ll.remove(1)
print "length:",ll.length()
print '----------------5-----------------'
ll.travel()

4)輸出:


堆棧

1.含義:堆棧(英語:stack),也可直接稱棧,在計算機科學中,是一種特殊的串列形式的數據結構,它的特殊之處在於只能允許在鏈接串列或陣列的一端(稱爲堆疊頂端指標,英語:top)進行加入資料(英語:push)和輸出資料(英語:pop)的運算。另外堆疊也可以用一維陣列或連結串列的形式來完成。堆疊的另外一個相對的操作方式稱爲佇列;由於堆疊數據結構只允許在一端進行操作,因而按照後進先出(LIFO, Last In First Out)的原理運作

2.特點:先入後出,後入先出;除頭尾節點之外,每個元素有一個前驅,一個後繼

3.操作:

  • is_empty:判斷棧是否爲空
  • peek:返回棧頂元素
  • size:返回棧的大小
  • push:把新的元素堆進棧裏面
  • pop:把棧頂元素丟出去
# -*- coding: utf-8 -*-

class Stack(object):
    __slots__ = ('__items')   #限定Stack類的成員只有__items(類成員)

    # 初始化棧爲空列表
    def __init__(self):
        self.__items = []

    # 判斷棧是否爲空,返回布爾值
    def is_empty(self):
        return self.__items == []

    # 返回棧頂元素
    def peek(self):
        return self.__items[len(self.__items) - 1]

    # 返回棧的大小
    def size(self):
        return len(self.__items)

    # 把新的元素堆進棧裏面(程序員喜歡把這個過程叫做壓棧,入棧,進棧……)
    def push(self, item):
        self.__items.append(item)

    # 把棧頂元素丟出去(程序員喜歡把這個過程叫做出棧……)
    def pop(self):
        return self.__items.pop()

# 初始化一個棧對象
my_stack = Stack()
# 把'h'丟進棧裏
my_stack.push('h')
# 把'a'丟進棧裏
my_stack.push('a')
# 看一下棧的大小(有幾個元素)
print my_stack.size()
# 打印棧頂元素
print my_stack.peek()
# 把棧頂元素丟出去,並打印出來
print my_stack.pop()
# 再看一下棧頂元素是誰
print my_stack.peek()
# 這個時候棧的大小是多少?
print my_stack.size()
# 再丟一個棧頂元素
print my_stack.pop()
# 看一下棧的大小
print my_stack.size
# 棧是不是空了?
print my_stack.is_empty()

4)輸出:


隊列

1)含義:和堆棧類似,唯一的區別是隊列只能在隊頭進行出隊操作,所以隊列是是先進先出(FIFO, First-In-First-Out)的線性表

2)特點:先入先出,後入後出;除尾節點外,每個節點有一個後繼;(可選)除頭節點外,每個節點有一個前驅

3)操作:

  • inqueue():一次入隊一個
  • many_in_queue():一次入隊多個
  • outqueue():出隊
  • show():顯示隊列
  • head():隊列的頭部
  • tail():隊列的尾部
  • isempty():判斷隊列是否爲空
  • length():隊列長度
# -*- coding: utf-8 -*-

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

    # 一次入隊一個
    def inqueue(self,item):
        self.queue.append(item)

    # 一次入隊多個
    def many_in_queue(self,*args):
        self.queue.extend(args)

    # 出隊
    def outqueue(self):
        if not self.queue == []:
            self.queue.pop(0)
        else:
            return None

    # 顯示隊列
    def show(self):
        for i in self.queue:
            print i

    # 隊列的頭部
    def head(self):
        if not self.queue == [] :
            print self.queue[0]
        else :
            return None

    # 隊列的尾部
    def tail(self):
        if not self.queue == []:
            print self.queue[-1]
        else :
            return None

    # 是否爲空
    def isempty(self):
        return self.queue == []

    # 長度
    def length(self):
        print len(self.queue)

q1 = queue()
q1.inqueue(1)
q1.show()
print '----------1-----------'
q1.many_in_queue(3,4,5)
q1.show()
print '----------1-----------'
q1.outqueue()
q1.show()
print '----------1-----------'
q1.head()
print '----------1-----------'
q1.tail()
print '----------1-----------'
q1.length()
q1.isempty()

4)輸出:


二叉樹

1)定義:二叉樹是每個結點最多有兩個子樹的樹結構。它有五種基本形態:二叉樹可以是空集;根可以有空的左子樹或右子樹;或者左、右子樹皆爲空


2)特點:性質1:二叉樹第i層上的結點數目最多爲2i-1(i>=1);性質2:深度爲k的二叉樹至多有2k-1個結點(k>=1);性質3:包含n個結點的二叉樹的高度至少爲(log2n)+1;性質4:在任意一棵二叉樹中,若終端結點的個數爲n0,度爲2的結點數爲n2,則n0=n2+1

3)操作

# -*- coding: utf-8 -*-

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

class Tree(object):
    def __init__(self):
        self.root = None

    def add(self, item):
        node = Node(item)
        if self.root is None:
            self.root = node
        else:
            q = [self.root]

            while True:
                pop_node = q.pop(0)
                if pop_node.child1 is None:
                    pop_node.child1 = node
                    return
                elif pop_node.child2 is None:
                    pop_node.child2 = node
                    return
                else:
                    q.append(pop_node.child1)
                    q.append(pop_node.child2)

    def traverse(self):  # 層次遍歷
        if self.root is None:
            return None
        q = [self.root]
        res = [self.root.item]
        while q != []:
            pop_node = q.pop(0)
            if pop_node.child1 is not None:
                q.append(pop_node.child1)
                res.append(pop_node.child1.item)

            if pop_node.child2 is not None:
                q.append(pop_node.child2)
                res.append(pop_node.child2.item)
        return res

    def preorder(self,root):  # 先序遍歷
        if root is None:
            return []
        result = [root.item]
        left_item = self.preorder(root.child1)
        right_item = self.preorder(root.child2)
        return result + left_item + right_item

    def inorder(self,root):  # 中序序遍歷
        if root is None:
            return []
        result = [root.item]
        left_item = self.inorder(root.child1)
        right_item = self.inorder(root.child2)
        return left_item + result + right_item

    def postorder(self,root):  # 後序遍歷
        if root is None:
            return []
        result = [root.item]
        left_item = self.postorder(root.child1)
        right_item = self.postorder(root.child2)
        return left_item + right_item + result

t = Tree()
for i in range(10):
    t.add(i)
print u'層序遍歷:',t.traverse()
print u'先序遍歷:',t.preorder(t.root)
print u'中序遍歷:',t.inorder(t.root)
print u'後序遍歷:',t.postorder(t.root)

4)輸出:


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