使用Python实现常见的数据结构

队列

# 队列
class Queue(object):
    def __init__(self):
        self.items= []

    # 是否为空
    @property
    def is_empty(self):
        return self.items == []

    # 进队列
    def enqueue(self,item):
        self.items.insert(0,item)

    # 出队列
    def dequeue(self):
        return self.items.pop()

    # 队列大小
    @property
    def size(self):
        return len(self.items)

if __name__ == '__main__':
    q = Queue()

    print(f"q is empty? <{q.is_empty}>")

    q.enqueue("whw1")
    q.enqueue("whw2")
    q.enqueue("whw3")

    print(f"q is empty? <{q.is_empty}>")
    print(f"q's size is {q.size}")

    print(q.dequeue())

    print(f"q's size is {q.size}")
队列

双端队列

# 双端队列
class Dqueue(object):
    def __init__(self):
        self.items = []

    # 判断是否为空
    @property
    def is_empty(self):
        return self.items == []

    # 在头部添加元素
    def add_front(self,item):
        self.items.insert(0,item)

    # 在队尾添加元素
    def add_end(self,item):
        self.items.append(item)

    # 从头部删除元素
    def remove_front(self):
        return self.items.pop(0)

    # 从尾部删除元素
    def remove_end(self):
        return self.items.pop()

    # 队列的大小
    @property
    def size(self):
        return len(self.items)


if __name__ == '__main__':
    dq = Dqueue()

    print(f"dq is empty? <{dq.is_empty}>")

    dq.add_front("whw1")
    dq.add_front("whw2")

    print(f"dq is empty? <{dq.is_empty}>")
    print(f"dq's size: {dq.size}")
    print(dq.remove_front())


    dq.add_end("huoying1")
    dq.add_end("huoying2")

    print(dq.remove_end())

    print(f"dq's size is: {dq.size}")
双端队列

双端链表

# 双端链表节点
class Node(object):
    def __init__(self,item):
        self._item = item
        self._next = None
        self._prev = None

# 双端链表
class DoubLinkedList(object):
    def __init__(self):
        self._head = None

    # 是否为空
    @property
    def is_empty(self)->bool:
        return self._head is None

    # 链表长度    
    @property
    def length(self)->int:
        cur = self._head
        count = 0
        while cur is not None:
            count += 1
            cur = cur._next
        return count    

    # 遍历链表
    def travel(self):
        cur = self._head
        while cur is not None:
            print(cur._item)
            cur = cur._next
        print("DoubLinkedList has been traveled!")

    # 头部添加元素
    def add(self,item):
        # 要添加的节点
        node = Node(item)
        # 如果是空链表将_head指向node!
        if self.is_empty:
            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)
        # 空链表将_head指向node!
        if self.is_empty:
            self._head = node
        else:
            # 先移动链表到尾部
            cur = self._head
            while cur._next is not None:
                cur = cur._next
            # 将尾节点的_next指向node,遍历完后cur暂时是尾节点
            cur._next = node
            # 将node的prev指向cur,此时node就是尾节点了
            node._prev = cur

    # 查找元素是否存在
    def search(self,item)->bool:
        cur = self._head
        while cur is not None:
            if cur._item == item:
                return True
            cur = cur._next
        # 没找到返回False
        return False

    ### 指定位置插入节点
    def insert(self,pos,item):
        # 头部添加
        if pos <= 0:
            self.add(item)
        # 尾部添加
        elif pos >= self.length:
            self.append(item)
        # 按照位置添加
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 挪动到指定位置的前一个位置
            while count < (pos-1):
                count += 1
                cur = cur._next
            # 将node的prev指向cur,此时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):
        # 空链表直接返回None
        if self.is_empty:
            return 
        cur = self._head
        # 第一个元素就是要删除的item的话
        if cur._item == item:
            # 如果链表只有一个节点,直接让_head为None即可
            if cur._next is None:
                self._head = None
            else:
                # 将第二个节点的prev设置为None
                cur._next._prev = None
                # 将_head指向第二个节点
                self._head = cur._next
            return 
        # 遍历链表
        while cur is not None:
            if cur._item == item:
                # 注意这里需要判断一下cur是否是最后一个节点,最后一个节点的_next是None,None没有_prev
                if cur._next is not None:
                    # 将cur的前一个节点的_next指向cur的下一个节点
                    cur._prev._next = cur._next
                    # 将cur的后一个节点的_prev指向cur的前一个节点
                    cur._next._prev = cur._prev
                    break
                # 正好删除的是最后一个节点
                else:
                    # 直接让最后一个节点的上一个节点的_next指向None,注意break!
                    cur._prev._next = None
                    break
            else:
                cur = cur._next
        # 如果没有删除的元素,什么也不做!


if __name__ == '__main__':
    lst = DoubLinkedList()

    print(f"lst is empty? <{lst.is_empty}>")

    lst.add(1)
    lst.add(2)
    lst.travel()

    lst.append(33)
    lst.append(44)
    lst.travel()

    lst.insert(2,"OK")
    lst.travel()

    print(f"lst's length is {lst.length}")

    lst.remove(2)
    lst.remove(33)
    lst.remove(44)
    lst.travel()

    print(f"lst is empty? <{lst.is_empty}>")

    print(f"Does OK in lst? <{lst.search('OK')}>")
    print(f"Does 666 in lst? <{lst.search('666')}>")
双端链表

单链表

# coding:utf-8

# 单链表的节点
class SingleNode(object):
    def __init__(self,item):
        # self._item存放元素
        self._item = item
        # self._next是下一个节点的标识
        self._next = None


# 单链表
class SingleLinkList(object):
    def __init__(self):
        self._head = None

    # 判断链表是否为空
    @property
    def is_empty(self)->bool:
        return self._head is None

    # 求链表的长度
    @property
    def length(self)->int:
        # cur一开始指向头节点
        cur = self._head
        count = 0
        # 注意尾节点也指向None
        while cur is not None:
            count += 1
            # cur向后移动一个节点,注意这里的cur其实已经是SingleNode对象了,有_next属性!
            cur = cur._next
        return count

    # 遍历链表
    def travel(self):
        cur = self._head
        while cur is not None:
            print(cur._item)
            cur = cur._next
        print("SingleLinkList has been traveled!")

    # 头部添加元素
    def add(self,item):
        # 先创建一个保存item的节点
        node = SingleNode(item)
        # 将新节点的_next指向头结点,即指向_head指向的位置
        node._next = self._head
        # 将链表的头_head指向新节点
        self._head = node

    # 尾部添加元素
    def append(self,item):
        node = SingleNode(item)
        # 判断链表是否为空,为空的话将_head指向新的节点
        if self.is_empty:
            self._head = node
        # 若不为空,则找到尾部,将尾节点的next指向新的节点
        else:
            cur = self._head
            while cur._next is not None:
                cur = cur._next
            cur._next = node

    # 指定位置添加元素
    def insert(self,pos,item):
        # 若指定位置pos在第一个元素之前,则执行头部插入add方法
        if pos <= 0:
            self.add(item)
        # 若指定位置pos超过链表尾部,则执行尾部插入append方法
        elif pos >= self.length:
            self.append(item)
        # 找到指定位置插入元素
        else:
            node = SingleNode(item)
            count = 0
            # pre表示pos的前一个位置pos-1,需要先从头节点开始移动到pre这个位置
            pre = self._head
            while count < (pos-1):
                count += 1
                pre = pre._next
            # 先将新节点node的next指向插入位置的节点
            node._next = pre._next
            # 再将“插入位置的前一个节点”的next指向新的节点
            pre._next = node

    # 删除节点
    def remove(self,item):
        cur = self._head
        pre = None
        while cur is not None:
            # 找到了指定元素
            if cur._item == item:
                # 如果第一个节点就是需要删除的节点
                if not pre:
                    # 将头指针指向头节点后的第一个节点
                    self._head = cur._next
                else:
                    # 将删除位置的前一个节点的next指向删除位置的后一个节点
                    pre._next = cur._next
                break
            # 没有找到指定的元素
            else:
                # 继续按链表后移节点
                pre = cur
                cur = cur._next

    # 查找节点是否存在
    def search(self,item)->bool:
        cur = self._head
        while cur is not None:
            if cur._item == item:
                return True
            cur = cur._next
        return False



if __name__ == '__main__':
    
    s = SingleLinkList()
    print(f"SingleLinkList is_empty? <{s.is_empty}>")

    s.add(11)
    s.add(12)
    s.travel()

    s.append(22)
    s.append(33)
    s.travel()

    s.insert(3,"666")
    s.travel()

    s.remove(22)
    s.travel()

    print(f"SingleLinkList is_empty? <{s.is_empty}>")

    print(f"Does 12 in SingleLinkList? <{s.search(12)}>")
    print(f"Does 22 in SingleLinkList? <{s.search(22)}>")
单链表

单向循环链表

# 节点类
class Node(object):
    def __init__(self,item):
        self._item = item
        self._next = None


# 单向循环链表
class SinCycLinkedList(object):
    def __init__(self):
        self._head = None

    # 判断链表是否为空
    @property
    def is_empty(self)->bool:
        return self._head is None

    # 求链表的长度
    @property
    def length(self)->int:
        if self.is_empty:
            return 0
        count = 1
        cur = self._head
        # 注意循环的条件
        while cur._next != self._head:
            count += 1
            cur = cur._next
        return count

    # 遍历链表
    def travel(self):
        if self.is_empty:
            return 
        # 第一个节点单独处理
        cur = self._head
        print(cur._item)
        # 注意循环的条件
        while cur._next != self._head:
            cur = cur._next
            print(cur._item)
        print("SinCycLinkedList has been traveled!")

    # 头部添加节点
    def add(self,item):
        # 实例化一个Node对象
        node = Node(item)
        if self.is_empty:
            # 循环单向链表尾节点指向头节点
            self._head = node
            node._next = self._head
        else:
            # 先将添加的节点指向_head
            node._next = self._head
            # 移动到链表的尾部,将尾部的节点的_next指向node
            cur = self._head
            while cur._next != self._head:
                cur = cur._next
            cur._next = node
            # _head指向新添加的node
            self._head = node    

    # 尾部添加节点
    def append(self,item):
        node = Node(item)
        # 空链表情况
        if self.is_empty:
            self._head = node
            node._next = self._head
        else:
            # 先移动到链表的尾部
            cur = self._head
            while cur._next != self._head:
                cur = cur._next
            # 将尾节点指向node
            cur._next = node
            # 将node指向头节点_head
            node._next = self._head

    # 指定位置添加节点
    def insert(self,pos,item):
        # 首部添加
        if pos <= 0:
            self.add(item)
        # 尾部添加
        elif pos >= self.length:
            self.append(item)
        # 指定位置添加
        else:
            node = Node(item)
            cur = self._head
            count = 0
            # 先移动到指定位置的前一个节点,注意这里与pos-1比较!
            while count < (pos-1):
                count += 1
                cur = cur._next
            # 先将node的下一个节点设置为cur的_next,然后再将cur的_next设置为node,注意顺序不能反!
            node._next = cur._next
            cur._next = node

    # 删除一个节点
    def remove(self,item):
        # 若链表为空则直接返回None
        if self.is_empty:
            return 
        # 先将cur指向头节点
        cur = self._head
        pre = None
        # 若头节点的元素正好是要查找的元素
        if cur._item == item:
            # 若链表不止有一个节点
            if cur._next != self._head:
                # 先找到尾节点,将尾节点的_next指向第二个节点
                while cur._next != self._head:
                    cur = cur._next
                # 注意cur现在就是尾节点,并且最后需要将self._head指向第二个节点!
                cur._next = self._head._next
                self._head = self._head._next
            # 链表只有一个节点直接让_head指向None
            else:
                self._head = None
        else:
            pre = self._head
            # 注意不删除第一个节点!
            while cur._next != self._head:
                # 找到了要删除的元素
                if cur._item == item:
                    pre._next = cur._next
                    return 
                # 否则pre与cur往前挪动位置
                pre = cur
                cur = cur._next
            # 临界情况:while循环结束还没找到的话,此时cur就是尾节点,需要单独处理
            if cur._item == item:
                # 尾部删除,让尾节点的上一个节点pre的_next指向头节点即可
                pre._next = cur._next

    # 查找节点是否存在
    def search(self,item)->bool:
        # 空链表直接返回False
        if self.is_empty:
            return False
        cur = self._head
        # 如果头节点正好是要找的元素
        if cur._item == item:
            return True
        # 否则遍历链表
        while cur._next != self._head:
            # 先移动再比较!
            cur = cur._next
            if cur._item == item:
                return True
        # 遍历完后还没找到就返回False
        return False


if __name__ == '__main__':
    lst = SinCycLinkedList()
    print(f"lst is empty? <{lst.is_empty}>")

    lst.add(1)
    lst.add(2)
    lst.travel()

    lst.append(33)
    lst.append(44)
    lst.travel()

    lst.insert(2,"OK")
    lst.travel()

    print(f"lst's length is {lst.length}")

    lst.remove(44)
    lst.travel()

    print(f"lst is empty? <{lst.is_empty}>")

    print(f"Does OK in lst? <{lst.search('OK')}>")
    print(f"Does 666 in lst? <{lst.search('666')}>")
单向循环链表

# 栈:last in first out
class Stack(object):
    def __init__(self):
        self.items = []

    # 是否为空
    @property
    def is_empty(self):
        return self.items == []

    # 添加元素——append在后面添加
    def push(self,item):
        self.items.append(item)    

    # 弹出元素——pop弹出最后面的元素
    def pop(self):
        return self.items.pop()

    # 返回栈顶元素
    @property
    def peek(self):
        return self.items[len(self.items)-1]

    # 返回栈的大小
    @property
    def size(self):
        return len(self.items)    

if __name__ == '__main__':
    s = Stack()

    print(f"s is empty? <{s.is_empty}>")

    s.push("hello")
    s.push("world")
    s.push("whw")    

    print(f"s is empty? <{s.is_empty}>")
    print(f"s's size is {s.size}")

    print(s.pop())

    print(s.peek)

二叉树

# coding:utf-8

class Node(object):
    """"""
    def __init__(self, item):
        self.elem = item
        self.lchild = None
        self.rchild = 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
            return
        queue = [self.root]
        while queue:
            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):
        """广度遍历"""
        if self.root is None:
            return
        queue = [self.root]
        while queue:
            cur_node = queue.pop(0)
            print(cur_node.elem, end=" ")
            if cur_node.lchild is not None:
                queue.append(cur_node.lchild)
            if cur_node.rchild is not None:
                queue.append(cur_node.rchild)

    def preorder(self, node):
        """先序遍历"""
        if node is None:
            return
        print(node.elem, end=" ")
        self.preorder(node.lchild)
        self.preorder(node.rchild)

    def inorder(self, node):
        """中序遍历"""
        if node is None:
            return
        self.inorder(node.lchild)
        print(node.elem, end=" ")
        self.inorder(node.rchild)

    def postorder(self, node):
        """后序遍历"""
        if node is None:
            return
        self.postorder(node.lchild)
        self.postorder(node.rchild)
        print(node.elem, end=" ")


if __name__ == "__main__":
    tree = Tree()
    tree.add(0)
    tree.add(1)
    tree.add(2)
    tree.add(3)
    tree.add(4)
    tree.add(5)
    tree.add(6)
    tree.add(7)
    tree.add(8)
    tree.add(9)
    tree.breadth_travel()
    print(" ")
    tree.preorder(tree.root)
    print(" ")
    tree.inorder(tree.root)
    print(" ")
    tree.postorder(tree.root)
    print(" ")
二叉树

~~

posted on 2020-02-12 09:46  江湖乄夜雨  阅读(410)  评论(0编辑  收藏  举报