Python(14)——Python中链表、栈、队列、二叉树的封装


1、链表的封装

链表和数组区别

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。

每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。 相比于线性表顺序结构,操作复杂。由于不必须按顺序存储,链表在插入的时候可以达到O(1)的复杂度,比另一种线性表顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间,而线性表和顺序表相应的时间复杂度分别是O(logn)和O(1)。

LeetCode题目:两数相加
给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

  • 请你将两个数相加,并以相同形式返回一个表示和的链表。
  • 你可以假设除了数字 0 之外,这两个数都不会以 0 开头。
    输出
    在这里插入图片描述
# 封装节点类
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next

    def travel(self, head):
        """遍历链表里面的每一个元素"""
        while head:
            print(head.val, end='')
            head = head.next
## 创建链表
def create_l1():
    # l1 = 2,4,3
    # l2 = 5, 6, 4
    l1 = ListNode()
    node1 = ListNode(val=2)
    node2 = ListNode(val=4)
    node3 = ListNode(val=3)
    l1.next = node1
    node1.next = node2
    node2.next = node3
    return  l1.next

def create_l2():
    # l1 = 2,4,3
    # l2 = 5, 6, 4
    l2 = ListNode()
    node1 = ListNode(val=5)
    node2 = ListNode(val=6)
    node3 = ListNode(val=4)
    l2.next = node1
    node1.next = node2
    node2.next = node3
    return  l2.next
def addTwoNumbers(l1: ListNode, l2: ListNode) -> ListNode: ## 两个链表中的数据对应相加,从左到右
    res = 0
    l3 = ListNode()
    cur = l3
    while(l1 or l2):
        if(l1):
            res += l1.val  # res=2
            l1 = l1.next
        if(l2):
            res += l2.val # res=2+5=7
            l2 = l2.next
        # res=10, val=0, res=>val val=res%10
        # res=14, val=4, 14%10=4
        l3.next = ListNode(res%10)
        l3 = l3.next
        # res=10, 进位为1, 10//10=1
        # res=14, 进位为1, 14//10=1
        res  //= 10
    if res == 1:
        l3.next = ListNode(1)
    return cur.next


if __name__ == '__main__':
    l1 = create_l1()
    l2 = create_l2()
    l1.travel(l1)
    l3=addTwoNumbers(l1,l2)
    l3.travel(l3)
输出:708

2、栈和队列的封装

2.1 栈的封装

栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为“栈顶”,另一固定端称为“栈底”,当栈中没有元素时称为“空栈”。向一个栈内插入元素称为是进栈(push);从一个栈删除元素称为是出栈(pop)。特点 :后进先出(LIFO)

在这里插入图片描述

在这里插入图片描述

class Stack(object):
    """栈的封装[1, 2, 3, 4]"""

    def __init__(self):
        self.stack = []

    def push(self, value):
        """入栈"""
        self.stack.append(value)
        print(f"入栈元素为{value}")

    def pop(self):
        """出栈"""
        if self.is_empty():
            raise  Exception("栈为空")
        item = self.stack.pop()
        print(f"出栈元素为{item}")
        return  item

    def is_empty(self):
        """判断栈是否为空"""
        return  len(self.stack) == 0

    def top(self):
        """返回栈顶元素"""
        if self.is_empty():
            raise  Exception("栈为空")
        return  self.stack[-1]

    def __len__(self):
        """魔术方法, len(object)自动执行的方法"""
        return  len(self.stack)

if __name__ == '__main__':
    stack = Stack()
    stack.push(1)
    stack.push(2)
    stack.push(3)
    print(len(stack))  # 3
    stack.pop()
    print(stack.is_empty()) # False
    print(stack.top())  # 2
输出:
入栈元素为1
入栈元素为2
入栈元素为3
3
出栈元素为3
False
2

2.2 队列的封装

队列是限制在一端进行插入操作和另一端删除操作的线性表,允许进行插入操作的一端称为“队尾”

允许进行删除操作的一端称为“队头”,当队列中没有元素时称为“空队”。特点 :先进先出(FIFO)

在这里插入图片描述

在这里插入图片描述

class Queue(object):
    """队的封装[ 2, 3, 4]"""

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

    def enqueue(self, value):
        """入队"""
        self.queue.append(value)
        print(f"入队元素为{value}")

    def dequeue(self):
        """出队"""
        if self.is_empty():
            raise  Exception("队列为空")
        item=  self.queue.pop(0)
        print(f"出队元素为{item}")
        return  item

    def is_empty(self):
        """判断队列是否为空"""
        return  len(self.queue) == 0

    def first(self):
        """返回队头元素"""
        if self.is_empty():
            raise  Exception("队列为空")
        return  self.queue[0]
    def last(self):
        """返回队尾元素"""
        if self.is_empty():
            raise  Exception("队列为空")
        return  self.queue[-1]

    def __len__(self):
        """魔术方法, len(object)自动执行的方法"""
        return  len(self.queue)

if __name__ == '__main__':
    queue=Queue()
    queue.enqueue(2)
    queue.enqueue(3)
    queue.enqueue(4)
    queue.dequeue()
    print(queue.is_empty())
    print(queue.first())
    print(queue.last())
输出:
入队元素为2
入队元素为3
入队元素为4
出队元素为2
False
3
4

3、二叉树封装

3.1 二叉树是啥

参考链接

3.2 二叉树遍历方法

在这里插入图片描述

二叉树的遍历主要有三种:

方法一:前序遍历
前序遍历就是先遍历根节点,然后遍历左节点,最后是右节点;
在这里插入图片描述

方法二:中序遍历
中序遍历就是先遍历左节点,然后遍历中间的根节点,最后是右节点;
在这里插入图片描述
方法三:后序遍历
后序遍历就是先遍历左节点,然后遍历是右节点,最后是中间的根节点。
在这里插入图片描述

class Node(object):
    """节点类"""
    def __init__(self, val=None, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right

class BinaryTree(object):
    """封装二叉树"""
    def __init__(self, root):
        self.root = root

    def pre_travel(self, root):
        """先序遍历: 根左右"""
        if (root != None):
            print(root.val)
            self.pre_travel(root.left)
            self.pre_travel(root.right)


    def in_travel(self, root):
        """中序遍历: 左根右"""
        if (root != None):
            self.in_travel(root.left)
            print(root.val)
            self.in_travel(root.right)

    def last_travel(self, root):
        """后序遍历: 左右根"""
        if (root != None):
            self.last_travel(root.left)
            self.last_travel(root.right)
            print(root.val)


if __name__ == '__main__':
    node1 = Node(1)
    node2 = Node(2)
    node3 = Node(3)
    node4 = Node(4)
    node5 = Node(5)
    node6 = Node(6)
    node7 = Node(7)
    node8 = Node(8)
    node9 = Node(9)
    node10 = Node(10)

    bt = BinaryTree(root=node1)
    node1.left = node2
    node1.right = node3
    node2.left = node4
    node2.right= node5
    node3.left = node6
    node3.right = node7
    node4.left = node8
    node4.right = node9
    node5.left = node10


    # 先序遍历
    bt.pre_travel(node1)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值