zoukankan      html  css  js  c++  java
  • 数据结构

    主要内容

    • 1. 树的概念
    • 2. 二叉树
    • 3.二叉搜索树
    • 4.AVL树
    • 5.B树 | B+ 树

    1. 树的概念

    1.1 简单概述

    • 树是一种数据结构 比如:目录结构
    • 树是一种可以递归定义的数据结构
    • 树是由n个节点组成的集合:
    • 如果n=0,那这是一棵空树;
    • 如果n>0,那存在1个节点作为树的根节点,其他节点可以分为m个集合,每个集合本身又是一棵树。

    1.2 一些基本的概念

    • 根节点、叶子节点 : A 根节点    P,Q是叶子结点
    • 树的深度(高度):  4 共有4层
    • 树的度  :任意一个节点有几个叉
    • 孩子节点/父节点 : 有上下级关系的节点
    • 子树

    2. 二叉树

    2.1 定义; 度不超过2的树(节点最多有两个叉)

     2.2 两种特殊的二叉树

    满二叉树 : 一个二叉树,如果每一个层的结点数都达到最大值,则这个二叉树就是满二叉树

    完全二叉树 : 叶节点只能出现在最下层和次下层,并且最下面一层的结点都集中在该层最左边的若干位置的二叉树  

    2.3 二叉树的存储方式

     (1) 顺序的存储方式 (列表)  ---- 只限于完全二叉树 ,其他的情况会浪费空间

         

    • 父节点和左孩子节点的编号下标有什么关系?0-1 1-3 2-5 3-7 4-9     i  -> 2i+1
    • 父节点和右孩子节点的编号下标有什么关系?0-2 1-4 2-6 3-8 4-10   i  -> 2i+2

    (2) 链式的存储方式

    将二叉树的节点定义为一个对象,节点之间通过类似链表的链接方式来连接

     节点的定义:

    class BiTreeNode:
        def __init__(self, data):
            self.data = data
            self.lchild = None
            self.rchild = None

     

    class BiTreeNode:
        def __init__(self, data):
            self.data = data
            self.lchild = None
            self.rchild = None
    
    a = BiTreeNode('A')
    b = BiTreeNode('B')
    c = BiTreeNode('C')
    d = BiTreeNode('D')
    e = BiTreeNode('E')
    f = BiTreeNode('F')
    g = BiTreeNode('G')
    
    e.lchild = a
    e.rchild = g
    a.rchild = c
    c.lchild = b
    c.rchild = d
    g.rchild = f
    
    root = e

    2.3 二叉树的遍历

    • 前序遍历 
      # 深度优先搜索 - 前序遍历(先序遍历)   
      def pre_order(root):
          if root: # 如果不是空树
              print(root.data, end='')
              pre_order(root.lchild)
              pre_order(root.rchild)
      
      pre_order(root)   #EACBDGF

      注: 先打印根节点,在递归左右孩子节点,会实现深度优先遍历

    • 中序遍历 -> 当用栈来解释,就是每次从左孩子返回,打印该节点
      # 深度优先搜索 - 中序遍历
      def in_order(root):
          if root: # 如果不是空树
              in_order(root.lchild)
              print(root.data, end='')
              in_order(root.rchild)
      
      in_order(root)    #ABCDEGF

      注: 先递归左孩子,再输出自己,再递归右孩子,意味着只有当每一个节点的左孩子全部打印,再打印自己,最后打印右孩子

    • 后续遍历
      # 深度优先搜索 - 后序遍历
      def post_order(root):
          if root: # 如果不是空树
              post_order(root.lchild)
              post_order(root.rchild)
              print(root.data, end='')
      
      post_order(root)    #BDCAFGE

      注: 先递归左子树,在递归有子树,最后输出自己   左子树,子树,节点

    • 层次遍历
      # 广度优先搜索 - 层次遍历
      def level_order(root):
          q = deque()
          q.append(root)
          while len(q)>0: # 只要队列不空
              n = q.popleft()
              print(n.data, end='')
              if n.lchild:
                  q.append(n.lchild)
              if n.rchild:
                  q.append(n.rchild)
      
      level_order(root)          #EAGCFBD 

     3. 二叉搜索树

    二叉搜索树是一颗二叉树且满足性质:设x是二叉树的一个节点。如果y是x左子树的一个节点,那么y.key ≤ x.key;如果y是x右子树的一个节点,那么y.key ≥ x.key.

    3.1 二叉树的创建 ,插入 ,遍历

    class BiTreeNode:
        def __init__(self, data):
            self.data = data
            self.lchild = None
            self.rchild = None
    
    
    class BST:
        def __init__(self, li):
            self.root = None
            for v in li:
                self.insert(v)
    
        def insert(self, key):
            if not self.root:
                self.root = BiTreeNode(key)
                return
            p = self.root
            while p:
                if key < p.data:
                    if p.lchild: # p有左子树
                        p = p.lchild
                    else:
                        p.lchild = BiTreeNode(key)
                        return
                elif key > p.data:
                    if p.rchild: # p有右子树
                        p = p.rchild
                    else:
                        p.rchild = BiTreeNode(key)
                        return
                else:
                    return
    
    
        def search(self, key):
            p = self.root
            while p:
                if key < p.data:
                    p = p.lchild
                elif key > p.data:
                    p = p.rchild
                else:
                    return True
            return False
    
    
        def in_order(self):
            def _in_order(root):
                if root:  # 如果不是空树
                    _in_order(root.lchild)
                    print(root.data, end=',')
                    _in_order(root.rchild)
            _in_order(self.root)

    注: 二叉搜索树的中序遍历是升序,也可以做排序,排序 O(nlogn)  但是占了空间

    3.2 二叉搜索树的删除  O(logn)

     如果要删除的是叶子结点,直接删除

     

    如果要删除的节点只有一个孩子:将此节点的父亲与孩子连接,然后删除该节点

    如果要删除的节点有两个孩子:将其右子树的最小节点(该节点最多有一个右孩子)删除,并替换当前节点

    3.3 二叉搜索树的效率

    • 平均情况下,二叉搜索树进行搜索的时间复杂度为O(nlogn)。
    • 最坏情况下,二叉搜索树可能非常偏斜  O(n^2)

    解决方案:

    • 随机化插入
    • AVL树

    5. B树 | B+树

  • 相关阅读:
    git初学【常用命令、上传项目到码云或从码云拉取、克隆项目】
    dedecms自学
    sublime3使用笔记
    路由功能
    bootstrap模态框篇【遇到的问题】
    justgage.js的使用
    fullpage.js使用方法
    js&jq遇到的问题(不断更新中)
    图灵完备——停机问题
    中断
  • 原文地址:https://www.cnblogs.com/wcx666/p/10692384.html
Copyright © 2011-2022 走看看