树的基本操作

树是一种来描述对象之间一对多关系的数据结构,可以是一对二,也可以是一对三,以此类推,但是二叉树应用广泛。

树的遍历

遍历一棵二叉树就是按某种次序系统地“访问”二叉树上的所有结点,并使每一个结点恰好被访问一次。所谓“访问”一个结点,是指对该结点的数据域进行某种处理,处理的内容依具体问题而定,通常比较简单。我们知道,遍历一个线性结构很容易,只须从开始结点出发顺序扫描每个结点即可。但是二叉树是一个非线性结构,每个结点可以有两个后继结点,因此需要寻找一种规律来系统地访问树中各结点。遍历运算的关键在于访问结点的“次序”,这种次序应保证二叉树上的每个结点均被访问一次且仅一次。
由定义可知,一棵二叉树由三部分组成:根、左子树和右子树。因此对于二叉树的遍历也可相应地分解成三项“子任务”:
①访问根结点;
②遍历左子树(即依次访问左子树上的全部结点);
   ③遍历右子树(即依次访问右子树上的全部结点)。
   因为左、右子树都是二叉树(可以是空二叉树),对它们的遍历可以按上述方法继续分解,直到每棵子树均为空二叉树为止。由此可见,上述三项子任务的次序决定了遍历的次序。若以D、L、R分别表示这三项子任务,则共有6种可能的次序:DLR、LDR、LRD、DRL、RDL和RLD。通常限定“先左后右”,即子任务②在子任务③之前完成,这样就只剩下前三种次序,按这三种进行的遍历分别称为*先根遍历(或前序遍历)、中根(或中序)遍历、后根(或后序)遍历。三种遍历方法的定义如下。*
   先根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:
   ①访问根结点;
   ②先根遍历左子树;
   ③先根遍历右子树。
   中根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作:
   ①中根遍历左子树;
   ②访问根结点;
   ③中根遍历右子树。
   后根遍历 若需遍历的二叉树为空,执行空操作;否则,依次执行下列操作
   ①后根遍历左子树;
   ②后根遍历右子树;
   ③访问根结点。
   显然,上述三种遍历方法的区别在于执行子任务“访问根结点”的“时机”不同;若最先(最后、在中间)执行此子任务,则为先根(后根、中根)遍历。
按某种遍历方法遍历一棵二叉树,将得到该二叉树上所有结点的访问序列. 除此之外树还可以进行层次遍历按层数从小到大,每层从左到右的顺序进行遍历,这种遍历叫做广义遍历,用队列实现。

树的顺序遍历

#include<cstdio>
#include<iostream>
using namespace std;
typedef struct A
{
    char c;
    A* l_child;
    A* r_child;
} tree;
tree* createtree()//建树
{
    tree* T;
    T=new tree;

    char c;
    c=getchar();
    if(c=='#')
    {
        T=NULL;
    }
    else
    {
        T->c=c;
        T->l_child=createtree();
        T->r_child=createtree();
    }
    return T;
}
void preorder(tree* T)//前序遍历
{
    if(T!=NULL)
    {
        printf("%c",T->c);
        preorder(T->l_child);
        preorder(T->r_child);
    }
}
void inorder(tree* T)//中序遍历
{
    if(T!=NULL)
    {
        inorder(T->l_child);
        printf("%c",T->c);
        inorder(T->r_child);
    }
}
void postorder(tree* T)//后序遍历
{
    if(T!=NULL)
    {
        postorder(T->l_child);
        postorder(T->r_child);
        printf("%c",T->c);
    }
}
int main()
{
    tree* T;
    T=createtree();
    preorder(T);
    printf("\n");
    inorder(T);
    printf("\n");
    postorder(T);
    printf("\n");
    return 0;
}

广义表建树

void genlist_createtree ()
{
    queue<tree*> s
    tree* T;  //分别代表根节点,和当前所要处理的节点。
    char c;
    int k;       //用来存储下一步该存储那个节点的状态,1代表左孩子,2代表右孩子    
    T->l_child=NULL;
    T->r_child=NULL;
    c=getchar();

    if(c!='#')
    {
        T->c=c;
    }
    while(c=getchar())
    {
        switch(c)
        {
            case '(':  
                s.push(T)
                k=1;
                break;
            case ',':
                k=2;
                break;
            case ')':
                s.pop();
                break;
            default:
                T=new tree;
                T->c=c;
                T->l_child=NULL;
                T->r_child=NULL;    
                if(k==1)
                    s.front()->l_child=T;
                else
                    s.front()->r_child=T;
        }
    }
}

以上是广义表建树过程实际上是相当于按照次序找根节点。本质上和顺序建树的思想一样都是将树将根,左孩子,右孩子按一定的顺序进行创建,只是一种用递归实现,一种用队列实现。

交换树的左右孩子

void exchangechild(tree* T)
{
    if(T)
    {
        tree* temp;
        if(T->l_child||T->r_child)
        {
            temp=T->l_child;
            T->l_child=T->r_child;
            T->r_child=temp;
            exchangechild(T->l_child);
            exchangechild(T->r_child);
        }
    }
}

求树的深度

int treedepth(tree* T)
{
    int ldepth;
    int rdepth;

    if(T==NULL)//找到叶子的子节点
        return 0;

    ldepth=treedepth(T->l_child);//每次找子节点的高度
    rdepth=treedepth(T->r_child);

    return (ldepth>rdepth)?(ldepth+1):(rdepth+1);//返回左右节点深度最大的。
}

求叶子节点的个数

int  leaf(tree* T)
{
    if(T==NULL)//如果树空返回 0
        return 0;
    if(T->l_child==NULL&&T->r_child==NULL)
        return 1;

    return leaf(T->l_child)+leaf(T->r_child);
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉排序也称为二叉搜索,它是一种特殊的二叉树,满足以下性质: 1. 左子中的所有节点的值均小于根节点的值; 2. 右子中的所有节点的值均大于根节点的值; 3. 左子和右子也都是二叉排序基本操作包括插入节点、删除节点和查找节点。下面是它们的实现: 1. 插入节点: 插入节点操作用于向二叉排序中插入一个新节点。从根节点开始,比较插入节点的值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。直到找到一个空位置,将新节点插入到该位置。 示例代码如下: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None def insert_node(root, val): if root is None: return TreeNode(val) if val < root.val: root.left = insert_node(root.left, val) else: root.right = insert_node(root.right, val) return root ``` 2. 删除节点: 删除节点操作用于从二叉排序中删除指定节点。分为三种情况: - 被删除节点没有子节点:直接删除即可; - 被删除节点只有一个子节点:将子节点替代被删除节点的位置; - 被删除节点有两个子节点:找到被删除节点的后继节点(右子中最小的节点),将后继节点的值复制到被删除节点,然后删除后继节点。 示例代码如下: ```python def find_min(node): while node.left is not None: node = node.left return node def delete_node(root, val): if root is None: return root if val < root.val: root.left = delete_node(root.left, val) elif val > root.val: root.right = delete_node(root.right, val) else: if root.left is None: return root.right elif root.right is None: return root.left else: successor = find_min(root.right) root.val = successor.val root.right = delete_node(root.right, successor.val) return root ``` 3. 查找节点: 查找节点操作用于在二叉排序中查找指定值的节点。从根节点开始,比较目标值与当前节点的值,如果小于当前节点的值,则进入左子,否则进入右子。如果找到匹配的节点,则返回该节点;如果遍历完整个仍未找到匹配的节点,则返回空。 示例代码如下: ```python def search_node(root, val): if root is None or root.val == val: return root if val < root.val: return search_node(root.left, val) else: return search_node(root.right, val) ``` 以上是二叉排序基本操作的实现。你可以根据需要调用这些函数来操作二叉排序
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值