数据结构-01回顾

  • 数据结构、算法、程序

    【1】数据结构: 解决问题时使用何种数据类型,数据到底如何保存,只是静态描述了数据元素之间的关系
    【2】算法: 解决问题的方法,为了解决实际问题而设计的,数据结构是算法需要处理的问题载体
    【3】程序: 数据结构 + 算法
  • 数据结构分类

    【1】线性结构 : 多个数据元素的有序集合
    1.1) 顺序存储 - 线性表
    a> 定义: 将数据结构中各元素按照其逻辑顺序存放于存储器一片连续的存储空间中
    b> 示例: 顺序表、列表
    c> 特点: 内存连续,溢出时开辟新的连续内存空间进行数据搬迁并存储 1.2) 链式存储 - 线性表
    a> 定义: 将数据结构中各元素分布到存储器的不同点,用记录下一个结点位置的方式建立联系
    b> 示例: 单链表、单向循环链表
    c> 特点:
    单链表: 内存不连续,每个节点保存指向下一个节点的指针,尾节点指针指向"None"
    单向循环链表: 内存不连续,每个节点保存指向下一个节点指针,尾节点指针指向"头节点"
    1.3) 栈 - 线性表
    a> 后进先出 - LIFO
    b> 栈顶进行入栈、出栈操作,栈底不进行任何操作
    c> 顺序存储实现栈、链式存储实现栈
    1.4) 队列 - 线性表
    a> 先进先出 - FIFO
    b> 队尾进行入队操作、队头进行出队操作
    c> 顺序存储实现队列、链式存储实现队列
  • 算法效率衡量-时间复杂度T(n)

    【1】定义: 算法执行步骤的数量
    
    【2】分类
    2.1) 最优时间复杂度
    2.2) 最坏时间复杂度 - 平时所说
    2.3) 平均时间复杂度 【3】时间复杂度大O表示法 T(n) = O(??)
    去掉执行步骤的系数、常数、低次幂 【4】常见时间复杂度排序
    O(1)<O(logn)<O(n)<O(nlogn)<O(n2)<O(n2logn)<O(n3)

数据结构-02笔记

作业讲解

链表作业题一

  • 题目描述 + 试题解析

    【1】题目描述
    输入一个链表,输出该链表中倒数第 k 个节点 【2】试题解析
    可将链表中的每一个元素保存到列表中,在列表中寻找倒数第 k 个元素
  • 代码实现

    class Node:
    """节点类"""
    def __init__(self, value):
    self.value = value
    self.next = None class Solution:
    def get_k_node(self, head, k):
    li = []
    cur = head
    while cur:
    li.append(cur)
    cur = cur.next if k < 0 or k > len(li):
    raise IndexError('list index out of range')
    return li[-k] if __name__ == '__main__':
    s = Solution()
    # 创建链表:Node(100) -> Node(200) -> Node(300) -> None
    head = Node(100)
    head.next = Node(200)
    head.next.next = Node(300)
    # 终端1:倒数第2个 Node(200)
    print(s.get_k_node(head, 2).value)
    # 终端2:倒数第8个 IndexError
    print(s.get_k_node(head, 8))

链表作业题二

  • 题目描述 + 试题解析

    【1】题目描述
    输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则 【2】试题解析
    a> 比较两个链表的头节点,确认合成后链表的头节点
    b> 继续依次比较两个链表元素的大小,将元素小的结点插入到新的链表中,直到一个链 表为空
  • 代码实现

    """
    输入两个单调递增的链表,输出两个链表合成后的链表,当然我们需要合成后的链表满足单调不减规则
    思路:
    1、最终程序返回的是: 合并后链表的头节点
    2、先确定新链表的头节点
    3、互相比较,移动值小的游标
    """
    class Node:
    def __init__(self, value):
    self.value = value
    self.next = None class Solution:
    def merge_two_link_list(self, head1, head2):
    # 1、确定新链表的头节点
    h1 = head1
    h2 = head2
    if h1 and h2:
    if h1.value >= h2.value:
    merge_head = h2
    h2 = h2.next
    else:
    merge_head = h1
    h1 = h1.next
    p = merge_head
    elif h1:
    return h1
    else:
    return h2
    # 2、开始遍历两个链表进行合并
    while h1 and h2:
    if h1.value <= h2.value:
    merge_head.next = h1
    h1 = h1.next
    else:
    merge_head.next = h2
    h2 = h2.next
    # 移动合并后的游标
    merge_head = merge_head.next
    # 循环结束后,一定有一个游标为None
    if h1:
    merge_head.next = h1
    elif h2:
    merge_head.next = h2 return p if __name__ == '__main__':
    s = Solution()
    # 链表1: 100 -> 200 -> 300 -> 400 -> None
    head1 = Node(100)
    head1.next = Node(200)
    head1.next.next = Node(300)
    head1.next.next.next = Node(400)
    # 链表2: 1 -> 200 -> 600 -> None
    head2 = Node(1)
    head2.next = Node(200)
    head2.next.next = Node(600)
    # 测试方法
    p = s.merge_two_link_list(head1, head2)
    while p:
    print(p.value, end=" ")
    p = p.next

链表作业题三

  • 题目描述 + 试题解析

    【1】题目描述
    输入两个链表,找出它们的第一个公共节点 【2】试题解析
    如果有公共节点,则两个链表公共节点后面的节点一定完全相同,因为节点有数据区和指针区,而next只能指向1个节点 思路:
    stack1 = [] 存储第1个链表中的节点
    stack2 = [] 存储第2个链表中的节点 两边同时pop,后面节点一定相同,一直找到最后1个相同的节点即可
  • 代码实现

    """
    输入两个链表,找出它们的第一个公共节点
    思路:
    1、两个链表中,从第一个公共节点开始,后面所有节点一定相同(都是公共节点)
    2、先把两个链表中所有的节点对象添加到两个列表中
    3、列表从后往前判断,到最后1个公共节点时返回
    示例: a is b
    """
    class Node:
    def __init__(self, value):
    self.value = value
    self.next = None class Solution:
    def get_first_public_node(self, head1, head2):
    # 1、创建2个列表,把节点添加进去
    li1 = []
    li2 = []
    cur1 = head1
    while cur1:
    li1.append(cur1)
    cur1 = cur1.next
    cur2 = head2
    while cur2:
    li2.append(cur2)
    cur2 = cur2.next # 从后往前依次判断两个列表中节点
    # li1 : [Node(100),Node(200),Node(300),Node(400)]
    # li2 : [Node(666),Node(300),Node(400)]
    node = None
    while li1 and li2 and li1[-1] is li2[-1]:
    node = li1.pop()
    li2.pop() return node if __name__ == '__main__':
    s = Solution()
    n100 = Node(100)
    n200 = Node(200)
    n300 = Node(300)
    n400 = Node(400)
    n666 = Node(666)
    # 链表1: 100 -> 200 -> 300 -> 400 -> None
    head1 = n100
    head1.next = n200
    n200.next = n300
    n300.next = n400
    # 链表2: 666 -> 300 -> 400 -> None
    head2 = n666
    head2.next = n300
    n300.next = n400
    # 测试方法
    print(s.get_first_public_node(head1, head2).value)

线性表 - 栈(LIFO)

  • 定义

    栈是限制在一端进行插入操作和删除操作的线性表(俗称堆栈),允许进行操作的一端称为"栈顶",另一固定端称为"栈底",当栈中没有元素时称为"空栈"
  • 特点

    【1】栈只能在一端进行数据操作
    【2】栈模型具有后进先出的规律(LIFO)

  • 顺序栈代码实现

    """
    顺序存储的方式实现栈
    思路:
    1、栈 :LIFO 后进先出
    2、设计
    列表尾部作为栈顶(入栈、出栈操作)
    列表头部作为栈底(不进行任何操作)
    """
    class Stack:
    def __init__(self):
    """初始化一个空栈"""
    self.elems = [] def is_empty(self):
    """判断栈是否为空栈"""
    return self.elems == [] def push(self, item):
    """入栈: 相当于在链表尾部添加1个元素"""
    self.elems.append(item) def destack(self):
    """出栈: 相当于在列表尾部弹出1个元素"""
    if self.is_empty():
    raise Exception('destack from empty stack')
    return self.elems.pop() if __name__ == '__main__':
    s = Stack()
    # 栈(栈底->栈顶): 100 200 300
    s.push(100)
    s.push(200)
    s.push(300)
    # 终端1: 300 200 100 异常
    print(s.destack())
    print(s.destack())
    print(s.destack())
    print(s.destack())
  • 链式栈代码实现

    """
    链式存储方式实现栈
    思路:
    1、栈:LIFO 后进先出
    2、设计
    链表头部作为栈顶(入栈、出栈操作)
    链表尾部作为栈底(不进行任何操作)
    """
    class Node:
    """节点类"""
    def __init__(self, value):
    self.value = value
    self.next = None class LinkListStack:
    def __init__(self):
    """初始化一个空栈"""
    self.head = None def is_empty(self):
    """判断是否为空栈"""
    return self.head == None def push(self, item):
    """入栈操作: 相当于在链表的头部添加一个节点"""
    node = Node(item)
    node.next = self.head
    self.head = node def pop(self):
    """出栈操作: 相当于删除链表头节点"""
    if self.is_empty():
    raise Exception('pop from empty LinkListStack')
    item = self.head.value
    self.head = self.head.next return item if __name__ == '__main__':
    s = LinkListStack()
    # 栈(栈底->栈顶):300 200 100
    s.push(100)
    s.push(200)
    s.push(300)
    # 终端1: 300
    print(s.pop())
    # 终端2: False
    print(s.is_empty())

线性表 - 队列(FIFO)

  • 定义

    队列是限制在两端进行插入操作和删除操作的线性表,允许进行存入操作的一端称为"队尾",允许进行删除操作的一端称为"队头"
  • 特点

    1) 队列只能在队头和队尾进行数据操作
    2) 队列模型具有先进先出规律(FIFO)

  • 顺序队列代码实现

    """
    顺序存储方式去实现队列模型
    思路:
    1、队列:FIFO 先进先出,队尾负责入队,队头负责出队
    2、设计:
    列表头部作为队头,负责出队
    列表尾部作为队尾,负责入队
    """
    class Queue:
    def __init__(self):
    """初始化一个空队列"""
    self.elems = [] def is_empty(self):
    """判断队列是否为空"""
    return self.elems == [] def enqueue(self, item):
    """队尾入队: append(item)"""
    self.elems.append(item) def dequeue(self):
    """队头出队: pop(0)"""
    if self.is_empty():
    raise Exception('dequeue from empty Queue')
    return self.elems.pop(0) if __name__ == '__main__':
    q = Queue()
    # 队列: 100 200 300
    q.enqueue(100)
    q.enqueue(200)
    q.enqueue(300)
    # 终端1: 100
    print(q.dequeue())
    # 终端2: False
    print(q.is_empty())
  • 链式队列代码实现

    """
    链式存储方式去实现队列
    思路:
    1、队列:FIFO 先进先出
    2、设计:
    链表头部作为队头,负责出队操作
    链表尾部作为队尾,负责入队操作
    """
    class Node:
    def __init__(self, value):
    self.value = value
    self.next = None class LinkListQueue:
    def __init__(self):
    """初始化一个空队列"""
    self.head = None def is_empty(self):
    """判断队列是否为空"""
    return self.head == None def enqueue(self, item):
    """队尾入队: 相当于在链表尾部添加一个节点"""
    node = Node(item)
    # 空队列情况
    if self.is_empty():
    self.head = node
    return
    # 非空队列
    cur = self.head
    while cur.next:
    cur = cur.next
    # 循环结束后,cur一定是指向了原链表尾节点
    cur.next = node
    node.next = None def dequeue(self):
    """队头出队: 相当于删除链表头节点"""
    if self.is_empty():
    raise Exception('dequeue from empty LinkListQueue')
    cur = self.head
    # 删除头节点
    self.head = self.head.next return cur.value if __name__ == '__main__':
    q = LinkListQueue()
    # 队列: 100 200 300
    q.enqueue(100)
    q.enqueue(200)
    q.enqueue(300)
    # 终端1: 100
    print(q.dequeue())
    # 终端2: False
    print(q.is_empty())

    栈和队列练习一

  • 题目描述+试题解析

    【1】题目描述
    用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。队列中的元素为 int 类型 【2】试题解析
    1、队列特点:先进先出(时刻铭记保证先进先出)
    2、栈 A 用来做入队列,栈 B 用来做出队列,当栈 B 为空时,栈 A 全部出栈到栈 B,栈B 再出栈(即出队列)
    3、精细讲解
    stack_a: 入队列(队尾)
    stack_b: 出队列(队头) stack_a队尾: [1,2,3]
    stack_b队头: []
    stack_b.append(stack_a.pop()) # [3,2,1]
    stack_b.pop() # 1
  • 代码实现

    """
    用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。队列中的元素为 int 类型
    思路:
    1、明确目标:实现队列(FIFO)
    2、实现载体:2个栈(LIFO)
    3、设计(计划使用顺序栈模型,而不使用链式栈模型)
    栈A(列表A):入队
    栈B(列表B):出队
    最终实现先进先出的效果,队列模型嘎然而生
    """
    class Solution:
    def __init__(self):
    """初始化2个顺序栈"""
    self.stack_a = []
    self.stack_b = [] def push(self, item):
    """入队操作:相当于在stack_a中添加一个元素"""
    self.stack_a.append(item) def pop(self):
    """出队操作:相当于在stack_b中弹出一个元素"""
    # 先从栈B中pop(),当B栈为空的时候,再去判断A栈是否为空
    if self.stack_b:
    return self.stack_b.pop() # B栈为空时,判断A栈,把A栈中所有的元素再次添加到B栈中
    while self.stack_a:
    self.stack_b.append(self.stack_a.pop()) # 循环结束后,A栈中所有的元素又全部到的B栈中
    if self.stack_b:
    return self.stack_b.pop() if __name__ == '__main__':
    s = Solution()
    # 入栈: 100 200 300
    s.push(100)
    s.push(200)
    s.push(300)
    # 终端1: 100
    print(s.pop())
    print(s.pop())
    print(s.pop())

树形结构

  • 定义

    树(Tree)是n(n≥0)个节点的有限集合T,它满足两个条件:有且仅有一个特定的称为根(Root)的节点;其余的节点可以分为m(m≥0)个互不相交的有限集合T1、T2、……、Tm,其中每一个集合又是一棵树,并称为其根的子树(Subtree)

  • 基本概念

    # 1. 树的特点
    * 每个节点有零个或者多个子节点
    * 没有父节点的节点称为根节点
    * 每一个非根节点有且只有一个父节点
    * 除了根节点外,每个子节点可以分为多个不相交的子树 # 2. 相关概念
    1) 节点的度: 一个节点的子树的个数
    2) 树的度: 一棵树中,最大的节点的度成为树的度
    3) 叶子节点: 度为0的节点
    4) 父节点
    5) 子节点
    6) 兄弟节点
    7) 节点的层次: 从根开始定义起,根为第1层
    8) 深度: 树中节点的最大层次

二叉树

  • 定义

    二叉树(Binary Tree)是n(n≥0)个节点的有限集合,它或者是空集(n=0),或者是由一个根节点以及两棵互不相交的、分别称为左子树和右子树的二叉树组成。二叉树与普通有序树不同,二叉树严格区分左孩子和右孩子,即使只有一个子节点也要区分左右

  • 二叉树的分类 - 见图

    【1】满二叉树
    所有叶节点都在最底层的完全二叉树 【2】完全二叉树
    对于一颗二叉树,假设深度为d,除了d层外,其它各层的节点数均已达到最大值,并且第d层所有节点从左向右连续紧密排列 【3】二叉排序树
    任何一个节点,所有左边的值都会比此节点小,所有右边的值都会比此节点大 【4】平衡二叉树
    当且仅当任何节点的两棵子树的高度差不大于1的二叉树


二叉排序树:

  • 二叉树 - 添加元素代码实现

    """
    二叉树
    """ class Node:
    def __init__(self, value):
    self.value = value
    self.left = None
    self.right = None class Tree:
    def __init__(self, node=None):
    """创建了一棵空树或者是只有树根的树"""
    self.root = node def add(self, value):
    """在树中添加一个节点"""
    node = Node(value)
    # 空树情况
    if self.root is None:
    self.root = node
    return # 不是空树的情况
    node_list = [self.root]
    while node_list:
    cur = node_list.pop(0)
    # 判断左孩子
    if cur.left is None:
    cur.left = node
    return
    else:
    node_list.append(cur.left) # 判断右孩子
    if cur.right is None:
    cur.right = node
    return
    else:
    node_list.append(cur.right)

广度遍历 - 二叉树

  • 广度遍历 - 代码实现

        def breadth_travel(self):
    """广度遍历 - 队列思想(即:列表的append()方法 和 pop(0) 方法"""
    # 1、空树的情况
    if self.root is None:
    return
    # 2、非空树的情况
    node_list = [self.root]
    while node_list:
    cur = node_list.pop(0)
    print(cur.value, end=' ')
    # 添加左孩子
    if cur.left is not None:
    node_list.append(cur.left)
    # 添加右孩子
    if cur.right is not None:
    node_list.append(cur.right)
    if __name__ == '__main__':
    t = Tree()
    t.add(1)
    t.add(2)
    t.add(3)
    t.add(4)
    t.add(5)
    t.add(6)
    t.add(7)
    t.add(8)
    t.add(9) t.trave()

深度遍历 - 二叉树

【1】遍历
沿某条搜索路径周游二叉树,对树中的每一个节点访问一次且仅访问一次。 【2】遍历方式
2.1) 前序遍历: 先访问树根,再访问左子树,最后访问右子树 - 根 左 右
2.2) 中序遍历: 先访问左子树,再访问树根,最后访问右子树 - 左 根 右
2.3) 后序遍历: 先访问左子树,再访问右子树,最后访问树根 - 左 右 根

【1】前序遍历结果: 1 2 4 8 9 5 10 3 6 7
【2】中序遍历结果: 8 4 9 2 10 5 1 6 3 7
【3】后序遍历结果: 8 9 4 10 5 2 6 7 3 1
  • 深度遍历 - 代码实现

    # 前序遍历
    def pre_travel(self, node):
    """前序遍历 - 根左右"""
    if node is None:
    return print(node.value, end=' ')
    self.pre_travel(node.left)
    self.pre_travel(node.right) # 中序遍历
    def mid_travel(self, node):
    """中序遍历 - 左根右"""
    if node is None:
    return self.mid_travel(node.left)
    print(node.value, end=' ')
    self.mid_travel(node.right) # 后续遍历
    def last_travel(self, node):
    """后序遍历 - 左右根"""
    if node is None:
    return self.last_travel(node.left)
    self.last_travel(node.right)
    print(node.value, end=' ')
  • 二叉树完整代码

    """
    python实现二叉树
    """ class Node:
    def __init__(self, value):
    self.value = value
    self.left = None
    self.right = None class Tree:
    def __init__(self, node=None):
    """创建了一棵空树或者是只有树根的树"""
    self.root = node def add(self, value):
    """在树中添加一个节点"""
    node = Node(value)
    # 空树情况
    if self.root is None:
    self.root = node
    return # 不是空树的情况
    node_list = [self.root]
    while node_list:
    cur = node_list.pop(0)
    # 判断左孩子
    if cur.left is None:
    cur.left = node
    return
    else:
    node_list.append(cur.left) # 判断右孩子
    if cur.right is None:
    cur.right = node
    return
    else:
    node_list.append(cur.right) def breadth_travel(self):
    """广度遍历 - 队列思想(即:列表的append()方法 和 pop(0) 方法"""
    # 1、空树的情况
    if self.root is None:
    return
    # 2、非空树的情况
    node_list = [self.root]
    while node_list:
    cur = node_list.pop(0)
    print(cur.value, end=' ')
    # 添加左孩子
    if cur.left is not None:
    node_list.append(cur.left)
    # 添加右孩子
    if cur.right is not None:
    node_list.append(cur.right) print() def pre_travel(self, node):
    """前序遍历 - 根左右"""
    if node is None:
    return print(node.value, end=' ')
    self.pre_travel(node.left)
    self.pre_travel(node.right) def mid_travel(self, node):
    """中序遍历 - 左根右"""
    if node is None:
    return self.mid_travel(node.left)
    print(node.value, end=' ')
    self.mid_travel(node.right) def last_travel(self, node):
    """后序遍历 - 左右根"""
    if node is None:
    return self.last_travel(node.left)
    self.last_travel(node.right)
    print(node.value, end=' ') if __name__ == '__main__':
    tree = Tree()
    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.add(10)
    # 广度遍历:1 2 3 4 5 6 7 8 9 10
    tree.breadth_travel()
    # 前序遍历:1 2 4 8 9 5 10 3 6 7
    tree.pre_travel(tree.root)
    print()
    # 中序遍历:8 4 9 2 10 5 1 6 3 7
    tree.mid_travel(tree.root)
    print()
    # 后序遍历:8 9 4 10 5 2 6 7 3 1
    tree.last_travel(tree.root)

二叉树练习一

  • 题目描述+试题解析

    【1】题目描述
    从上到下按层打印二叉树,同一层结点从左至右输出,每一层输出一行 【2】试题解析
    1、广度遍历,利用队列思想
    2、要有2个队列,分别存放当前层的节点 和 下一层的节点
  • 代码实现

    class Node:
    def __init__(self, value):
    self.value = value
    self.left = None
    self.right = None class Solution:
    def print_node_layer(self, root):
    # 空树情况
    if root is None:
    return []
    # 非空树情况
    cur_queue = [root]
    next_queue = []
    while cur_queue:
    cur_node = cur_queue.pop(0)
    print(cur_node.value, end=" ")
    # 添加左右孩子到下一层队列
    if cur_node.left:
    next_queue.append(cur_node.left)
    if cur_node.right:
    next_queue.append(cur_node.right)
    # 判断cur_queue是否为空
    # 为空:说明cur_queue已经打印完成,并且next_queue已经添加完成,交换变量
    if not cur_queue:
    cur_queue, next_queue = next_queue, cur_queue
    print() if __name__ == '__main__':
    s = Solution()
    p1 = Node(1)
    p2 = Node(2)
    p3 = Node(3)
    p4 = Node(4)
    p5 = Node(5)
    p6 = Node(6)
    p7 = Node(7)
    p8 = Node(8)
    p9 = Node(9)
    p10 = Node(10)
    p1.left = p2
    p1.right = p3
    p2.left = p4
    p2.right = p5
    p3.left = p6
    p3.right = p7
    p4.left = p8
    p4.right = p9
    p5.left = p10
    s.print_node_layer(p1)

二叉树练习二

  • 题目描述+试题解析

    【1】题目描述
    请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印, 第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推 【2】试题解析
    1、采用层次遍历的思想,用队列或者栈(先进先出或后进先出,此处二选一,我们选择栈)
    2、把每一层的节点添加到一个栈中,添加时判断是奇数层还是偶数层
    a) 奇数层:栈中存储时,二叉树中节点从右向左append,出栈时pop()则从左向右打印输出
    b) 偶数层: 栈中存储时,二叉树中节点从左向右append,出栈时pop()则从右向左打印输出
  • 代码实现

    """
    请实现一个函数按照之字形打印二叉树,即第一行按照从左到右的顺序打印, 第二层按照从右至左的顺序打印,第三行按照从左到右的顺序打印,其他行以此类推
    思路:
    1、选择一种数据结构来解决问题 - 栈(LIFO后进先出) - 顺序表(append() 和 pop())
    2、通过观察,发现了规律:
    2.1) 当前操作为奇数层时:先左后右 添加到下一层
    2.2) 当前操作为偶数层时:先右后左 添加到下一层
    """
    class Node:
    def __init__(self, value):
    self.value = value
    self.left = None
    self.right = None class Solution:
    def print_node_zhi(self, root):
    # 空树情况
    if root is None:
    return []
    # 非空树情况 - 栈思想(后进先出)
    cur_stack = [root]
    next_stack = []
    level = 1
    while cur_stack:
    cur_node = cur_stack.pop()
    print(cur_node.value, end=" ")
    # 添加左右孩子 - 当前层为奇数层从左至右,当前层为偶数层从右至左
    if level % 2 == 1:
    if cur_node.left:
    next_stack.append(cur_node.left)
    if cur_node.right:
    next_stack.append(cur_node.right)
    else:
    if cur_node.right:
    next_stack.append(cur_node.right)
    if cur_node.left:
    next_stack.append(cur_node.left) # 交换变量
    if not cur_stack:
    cur_stack, next_stack = next_stack, cur_stack
    level += 1
    print() if __name__ == '__main__':
    s = Solution()
    p1 = Node(1)
    p2 = Node(2)
    p3 = Node(3)
    p4 = Node(4)
    p5 = Node(5)
    p6 = Node(6)
    p7 = Node(7)
    p8 = Node(8)
    p9 = Node(9)
    p10 = Node(10)
    p1.left = p2
    p1.right = p3
    p2.left = p4
    p2.right = p5
    p3.left = p6
    p3.right = p7
    p4.left = p8
    p4.right = p9
    p5.left = p10
    s.print_node_zhi(p1)

数据结构(DataStructure)-02的更多相关文章

  1. 数据结构(DataStructure)与算法(Algorithm)、STL应用

    catalogue . 引论 . 数据结构的概念 . 逻辑结构实例 2.1 堆栈 2.2 队列 2.3 树形结构 二叉树 . 物理结构实例 3.1 链表 单向线性链表 单向循环链表 双向线性链表 双向 ...

  2. 数据结构笔记02:Java面试必问算法题

    1. 面试的时候,栈和队列经常会成对出现来考察.本文包含栈和队列的如下考试内容: (1)栈的创建 (2)队列的创建 (3)两个栈实现一个队列 (4)两个队列实现一个栈 (5)设计含最小函数min()的 ...

  3. java数据结构复习02

    1.递归问题 1.1汉诺塔问题(递归) 问题描述三个柱子,起初有若干个按大小关系顺序安放的盘子,需要全部移动到另外一个柱子上.移动规则:在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘.移动 ...

  4. mongodb配置文件

    启动MongoDB有2种方式,一是直接指定配置参数,二是指定配置文件.这里先介绍配置文件,启动方式如下: 1.mongod --config /etc/mongodb.conf 配置如下: verbo ...

  5. (一)MongoDB安装

    (一)MongoDB安装 mongodb 2018年03月06日 15时53分29秒 安装准备 启动mongodb 1.命令行参数启动 2.从配置文件启动 使用服务启动mongodb 参数解释 用户授 ...

  6. BUAA OO 2019 第三单元作业总结

    目录 总 JML规格化设计 理论基础 工具链 规格验证 验证代码 代码静态检查 自动生成测试样例 生成结果 错误分析 作业设计 第九次作业 架构 代码实现 第十次作业 架构 代码实现 第十一次作业 架 ...

  7. mongodb配置详解

    #启用日志文件,默认启用 journal=true #这个选项可以过滤掉一些无用的日志信息,若需要调试使用请设置为false quiet=false # 日志文件位置 logpath=/usr/loc ...

  8. 《Head First 设计模式》:剩下的模式

    正文 一.桥接模式 1.定义 桥接模式通过将实现和抽象分离开来,放在两个不同的类层次中,从而使得它们可以独立改变. 要点: 当一个类存在两个独立变化的维度,而且都需要进行扩展时,可以将其中一个维度抽象 ...

  9. Redis 系列(02)数据结构

    目录 Redis 系列(02)数据结构 Redis 系列目录 1. String 1.1 基本操作 1.2 数据结构 1.3 Redis数据存储结构 2. Hash 2.1 基本操作 2.2 数据结构 ...

  10. 数据结构与算法 —— 链表linked list(02)

    我们继续来看链表的第二道题,来自于leetcode: 两数相加 给定两个非空链表来代表两个非负整数,位数按照逆序方式存储,它们的每个节点只存储单个数字.将这两数相加会返回一个新的链表. 你可以假设除了 ...

随机推荐

  1. lisp入门资料收集

    1.一些文档 http://acl.readthedocs.io/en/latest/zhCN/index.html http://daiyuwen.freeshell.org/gb/lisp.htm ...

  2. C Ⅷ

    数组  int number[100];   //这个数组可以放100个数 int x; int cnt = 0; double sum = 0; scanf("%d", & ...

  3. Executors.newScheduledThreadPool()定时任务线程池

    定时任务线程池是由 Timer 进化而来 jdk中的计划任务 Timer 工具类提供了以计时器或计划任务的功能来实现按指定时间或时间间隔执行任务,但由于 Timer 工具类并不是以池 pool ,而是 ...

  4. PHP精度计算函数

    bcadd - 将两个高精度数字相加 bccomp - 比较两个高精度数字,返回-1, 0, 1 bcdiv - 将两个高精度数字相除 bcmod - 求高精度数字余数 bcmul - 将两个高精度数 ...

  5. 详解ResNet 网络,如何让网络变得更“深”了

    摘要:残差网络(ResNet)的提出是为了解决深度神经网络的"退化"(优化)问题.ResNet 通过设计残差块结构,调整模型结构,让更深的模型能够有效训练更训练. 本文分享自华为云 ...

  6. 重学c#系列—— explicit、implicit与operator[三十四]

    前言 我们都知道operator 可以对我们的操作符进行重写,那么explicit 和 implicit 就是对转换的重写. 正文 explicit 就是强制转换,然后implicit 就是隐式转换. ...

  7. SpringBoot——入门及原理

    SpringBoot 用来简化 Spring应用开发,约定大于配置,去繁从简,是由 Pivotal团队提供的全新框架.其设计目的是用来简化新 Spring应用的初始搭建以及开发过程.该框架使用了特定的 ...

  8. MyBatis 源码

    一.准备工作 MyBatis 工作流程:应用程序首先加载 mybatis-config.xml 配置文件,并根据配置文件的内容创建 SqlSessionFactory 对象:然后,通过 SqlSess ...

  9. C++ 测试框架 GoogleTest 初学者入门篇 甲

    *以下内容为本人的学习笔记,如需要转载,请声明原文链接微信公众号「ENG八戒」https://mp.weixin.qq.com/s/BS_u9A4EY50y4vDDuxkCAQ 开发者虽然主要负责工程 ...

  10. YUM下载全量依赖

    在离线的内网环境下进行安装一些软件的时候会出现依赖不完整的情况,一般情况下会使用如下方式进行下载依赖包 查看依赖包可以使用 yum deplist 进行查找 [root@localhost ~]# y ...