数据结构与算法之树和二叉树(一):二叉树基本操作的实现及应用

系列文章传送门:

数据结构与算法之树和二叉树(一):二叉树基本操作的实现及应用
数据结构与算法之线性表(二):链式表的实现和应用
数据结构与算法之线性表(三):顺序栈的实现和应用
数据结构与算法之线性表(四):链式栈的实现和应用
数据结构与算法之线性表(五):链式队列的实现和应用
数据结构与算法之线性表(六):顺序队列及循环队列的实现和应用

一.二叉树的基本操作实现

1.二叉树存储结构
二叉树可以用顺序表(完全二叉树比较适合)存储,也可以用链式结构(二叉链表)存储,其数据结构表示如下:

在这里插入图片描述
抽象出来就是这样:
二叉链表
2.二叉树遍历
二叉树遍历根据结点间遍历顺序可分为先序、中序、后序三种方式,
遍历有递归和非递归两种写法;如图为先序遍历的二叉树及其抽象树状图:
在这里插入图片描述
在这里插入图片描述
3.完全二叉树定义及其实现

在这里插入图片描述
以下为完全二叉树和其他二叉树的直观对比:
在这里插入图片描述
4.代码实现(所有代码均在Embarcadero DevC++6.0和VSCode 2021上编译运行通过):

#define ElementType char
#define Status int
#include<stdio.h>
#include<stdlib.h>
enum {TRUE=1, FALSE=0, ERROR=0, INFEASIBLE=-1, OVERFLOW=-2, OK=1};

typedef struct BiTNode{
    ElementType data;
    struct BiTNode *lchild;   
    struct BiTNode *rchild;   
}BiTNode, *BiTree;

    //  InitTree(&T); CreateTree(&T,definition);     
    //  ClearTree(&T); TreeEmpty(T); 
    //  TreeDepth(T); Root(T); 
    //  Value(T,cur_e); Assign(T, &cur_e, value); 
    //  Parent(T, cur_e); 
    //  LeftChild(T,cur_e); 
    //  RightSibling(T,cur_e);  
    //  InsertChild(&T,&p,i,c); DeleteChild(&T,&p,i);     
    //  TraverseTree(T,visit());
    //  DestroyTree(&T) 


BiTree count_k(BiTree &T, int &k)   //前序遍历计数结点个数,返回该结点指针
{
    if(!T || k<=0)
        return NULL;
    k--;
    if(k==0)
        return T;
    //分别数左右孩子
    if (count_k(T->lchild, k))
        return count_k(T->lchild, k);
    else
        return count_k(T->rchild, k); 
}

Status ValueLocate(BiTree T,int k, ElementType &e) //根据给定的值找对应的结点
{
    BiTree p;
    p = count_k(p,k);
    if(p)
    {
        e = p->data;
        return OK;
    }
    else
        return ERROR;  
}

int TreeDepth(BiTree T)
{
    int depth1,depth2;
    if(!T)
        return FALSE;
    depth1 = TreeDepth(T->lchild);    
    depth2 = TreeDepth(T->rchild);    
    return(depth1>depth2? depth1:depth2)+1;
}
Status TreeEmpty(BiTree T) 
{
    if (T==NULL)
        return TRUE;
    else
        return FALSE;
}
Status InitTree(BiTree &T)
{
    T = (BiTree)malloc(sizeof(BiTNode));
    return OK;
}
Status delsubtree(BiTree T)     //删除二叉树中所有以e为值的结点为根的子树
{
    if(T)
    {
        delsubtree(T->lchild);
        delsubtree(T->rchild);
        free(T);                //此删除仅仅释放空间
    }
    return OK;
}
Status DelTree(BiTree &T, ElementType e)
{
    if(T)
    {
        if(T->data==e)      //找到该删除的结点,把T及其子树空间释放
        {
            delsubtree(T);      
            T = NULL;
        }
        else
        {
            DelTree(T->lchild,e);
            DelTree(T->rchild,e);
        }        
    }
    return OK;
}
Status DestroyTree(BiTree &T)
{
     if(T)
    {
        delsubtree(T);      
        T = NULL;
        DelTree(T->lchild,T->lchild->data);
        DelTree(T->rchild,T->rchild->data);
    }
    return OK;   
}

Status PreorderTraverse(BiTree T, Status (*visit)(ElementType)) //前序遍历二叉树
{
    if(T)
    {
        if(visit(T->data))
            if(PreorderTraverse(T->lchild, visit))
                if(PreorderTraverse(T->rchild, visit))
                    return OK;
        return ERROR;
    }   
    else 
        return OK;
}

Status print(ElementType e)
{
    printf("%c->",e);
    return OK;
}

Status CreateTree(BiTree &T)
{
    ElementType e;
    scanf("%c",&e);     //先序创建一棵二叉树,由指针T指向其根结点
    if (e=='@')
        T = NULL;
    else
    {
        if(!(T= (BiTree)malloc(sizeof(BiTNode))))
            exit(OVERFLOW);        	
        T->data = e;
        CreateTree(T->lchild);
        CreateTree(T->rchild);
    }
    return OK;
}//CreateTree


int main()
{
    //输入:ABD@@EF@H@@G@@C@@ (@表示空树),深度为5
    BiTree T;
    ElementType e;
    InitTree(T);
    CreateTree(T);
    PreorderTraverse(T,print);
    int depth = TreeDepth(T);
    printf("二叉树深度:%d",depth);
    if(!T)
    	printf("错误.\n");
    ValueLocate(T,3,e);
    printf("第3个结点的结果是:%c",e);
    return 0;
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
二叉树是一种常见的数据结构,它由节点组成,每个节点最多有两个子节点:左子节点和右子节点。下面是二叉树的一些基本操作: 1. 插入操作:向二叉树中插入一个节点。如果树为空,则新节点将成为根节点。否则,我们需要找到合适的位置来插入新节点。通常,我们从根节点开始,按照一定规则(例如比较节点值)向左或向右遍历树,直到找到一个空位置来插入新节点。 2. 删除操作:从二叉树中删除一个节点。删除操作有三种情况:(1)被删除的节点没有子节点,这种情况下,只需将其父节点对应的子节点指针置为空即可。(2)被删除的节点有一个子节点,这种情况下,将其子节点替代被删除的节点即可。(3)被删除的节点有两个子节点,这种情况下,需要找到它的后继节点(通常是右子树中最小的节点),将后继节点的值复制给要删除的节点,并删除后继节点。 3. 查找操作:在二叉树中查找一个特定的值。从根节点开始,按照一定规则遍历树,直到找到目标值或者遍历完整个树。 4. 遍历操作:遍历二叉树可以按照不同的方式进行,常见的有三种遍历方式:前序遍历、中序遍历和后序遍历。前序遍历先访问根节点,在递归地遍历左子树和右子树;中序遍历先递归地遍历左子树,再访问根节点,最后递归地遍历右子树;后序遍历先递归地遍历左子树和右子树,最后访问根节点。 5. 翻转操作:将二叉树左右子节点交换。可以通过递归或迭代的方式实现。 这些是二叉树的一些基本操作,它们在实际应用中非常常见且有广泛的应用

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值