Mini-Notes: 数据结构与算法-[第二部分]树

前言
这个Mini-Notes开始于2016年4月18日下午,我想要认认真真把它写好,我也会认认真真把它写好。

  • 满二叉树是指这样的一种二叉树:除最后一层外,每一层上的所有结点都有两个子结点。在满二叉树中,每一层上的结点数都达到最大值,即在满二叉树的第k层上有2k-1个结点,且深度为m的满二叉树有2m-1个结点。
  • 完全二叉树是指这样的二叉树:除最后一层外,每一层上的结点数均达到最大值;在最后一层上只缺少右边的若干结点。

  • 回答几个问题
    树

    1. 什么是结点的深度?根结点的深度是多少?
      (从上往下,根到结点的所经过路径的边数,A的深度是0)
    2. 什么是结点的高度?叶子结点的高度是多少?
      (从下往上,结点到最远的叶子结点所经过路径的边数,G、H、F、D的高度是0,B的高度是2,C的高度是1)
    3. 什么是树的高度?
      (树的高度就是根结点的高度)
    4. 什么是二叉树?
      (二叉树的每个结点最多有两个子结点)
    5. 什么是Expression Trees?
      (An expression is a binary tree such that every node is labeled by a binary operator or unary operator, its left subtree denotes its left operand and right subtree its right operand.)
      An Expression Tree

二叉树:Sequential Storage 顺序存储

二叉树顺序存储

一个更加natrual的实现方法是linked storage:每个结点有两个指针,分别指向它的左右子树。

二叉树的遍历

Sicily 1156 Binary tree二叉树的遍历

前序遍历:根左右
中序遍历:左根右
后序遍历:左右根
(简单地来说,根在什么位置就是什么遍历)
层次遍历:若树为空,则空操作返回,否则从树的第0层,也就是根结点开始访问,从上而下逐层遍历,在同一层中,按从左到右的顺序对结点逐个访问。

一个典型的前序遍历算法框架:

void preorder(Binary_node * sub_root)
{
    if (sub_root != NULL)
    {
        cout << sub_root->data << " ";
        preorder(sub_root->left);
        preorder(sub_root->right);
    }
}

一个典型的中序遍历算法框架:

void inorder(Binary_node * sub_root)
{
    if (sub_root != NULL)
    {
        inorder(sub_root->left);
        cout << sub_root->data << " ";
        inorder(sub_root->right);
    }
}

一个典型的后序遍历算法框架:

void postorder(Binary_node * sub_root)
{
    if (sub_root != NULL)
    {
        postorder(sub_root->left);
        postorder(sub_root->right);
        cout << sub_root->data << " ";
    }
}

一个典型的层次遍历算法框架:

void traversal(BinaryNode *p)
{
    queue<BinaryNode*> q;
    BinaryNode *cur;
    if (p != NULL) 
        q.push(p);
    while (!q.empty()) 
    {
        cur = q.front();
        q.pop();
        printf("%d ", cur->data);
        if (cur->left != NULL) 
            q.push(cur->left);
        if (cur->right != NULL) 
            q.push(cur->right);
    }
}

Construct Binary Tree from Different Traversal Orders

问题1:

  • 问题描述:给定树的前序遍历和中序遍历,构造出这棵树。
  • 解决问题的基本思想:根据前序遍历得到根,在中序遍历中以那个根来划分左右子树。

问题2:

  • 问题描述:给定树的前序遍历和后序遍历,构造出这棵树。
  • 解决问题的基本思想:这棵树有可能不是唯一的。

Binary Search Trees(二叉查找树)

  • 什么是二叉查找树?
    1. 结点的左孩子比它小
    2. 右孩子比它大
    3. 左右子树也是二叉查找树

递归版

Tree Search 递归版

非递归版

Tree Search 非递归版

Method for Insertion

二叉查找树的插入方法

Removal Method

Removal Method - 1

Removal Method - 2

Removal Method - 3

  • 如果要删除的是个叶子结点,直接删,赋值为NULL;
  • 如果要删除的结点有一个子树,赋值为该子树的根结点;
  • 如果有两个子树,则找到要删除的结点的左子树的最右孩子w,然后替换该结点w到x那个位置。为什么可以这样做?因为可以放在x这个位置,意味着要比x的左孩子大,比x的右孩子小。本来w在x左子树,所以必定比x小,而x一开始必然小于其右孩子,所以w小于x的右孩子。因为w在x的左孩子的右子树上,所以w必定比x的左孩子大。

Removal Method的代码实现

平衡二叉查找树:AVL Trees

AVL得名于它的发明者G.M.Adel’son-Vel’ski and E.M. Landis

  • 什么是AVL树?
    AVL树是一个二叉查找树,该二叉查找树的左子树和右子树的高度最多相差1,并且它的左子树和右子树也是一个AVL树。

General Tree Definitions

  • 回答几个问题
    1. 什么是rooted tree?
    2. 什么是ordered tree?
    3. 什么是forest?
    4. 什么是orchard?

Tree Representations树的表示方法

Parent Method(双亲表示法)

双亲表示法-1

双亲表示法-2

Multiple links(多重链表表示法)

多重链表表示法-1

多重链表表示法-2

Child-link孩子链表表示法

孩子链表表示法-1

孩子链表表示法-2

First child next sibling(孩子兄弟表示法)

孩子兄弟表示法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值