数据结构_二叉树&树_基本操作的c++实现

本文介绍了二叉树的顺序存储和链式存储两种方式,并详细阐述了后序遍历、求树深度、层序遍历等算法。同时,探讨了线索二叉树的概念,包括中序线索化及其前驱后继节点查找,以及二叉排序树的查找和插入操作。这些内容对于理解和操作二叉树具有重要意义。
摘要由CSDN通过智能技术生成
#include <iostream>

using namespace std;

//二叉树
/*---------------------二叉树的顺序存储---------------*/
//定义
#define MaxSize 100
struct TreeNode{
    int value;    //结点中的数据元素
    bool isEmpty;   //结点是否为空
};

TreeNode t[MaxSize];//定义一个长度为MaxSize的数组t,按照从上至下、从左至右的顺序依次存储完全二叉树中的各个结点

//初始化
bool InitTree(TreeNode t[]){
    for (int i=0;i<MaxSize;i++)
        t[i].isEmpty=true;            //初始时结点必须都为空
    return true;
}

/*---------------------二叉树的链式存储---------------*/
//定义
struct ElemType{
    int value;
};

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

//二叉树的遍历
//后序遍历
void PostOrder(BiTree T){
    if(T!=NULL){
        PostOrder(T->lchild);
        PostOrder(T->rchild);
        printf("%d\n",T->data.value);
    }
}

//求树的深度
int treeDepth(BiTree T){
    if(T==NULL){
        return 0;
    }
    else{
        int l=treeDepth(T->lchild);
        int r=treeDepth(T->rchild);
        return l>r?l+1:r+1;
    }
}

//二叉树的层序遍历(需要借助一个辅助队列实现)
//链式队列结点
typedef struct LinkNode{
    BiTNode *data;          //!存指针而不是结点
    struct LinkNode *next;
}LinkNode;

typedef struct{
    LinkNode *front,*rear;
}LinkQueue;

void InitQueue(LinkQueue Q);
bool EnQueue(LinkQueue Q,BiTree T);
bool DeQueue(LinkQueue Q,BiTree T);
bool IsEmpty(LinkQueue Q);
void visit(BiTree p);
void LevelOrder(BiTree T){
    LinkQueue Q;
    InitQueue(Q);
    BiTree p;
    EnQueue(Q,T);
    while(!IsEmpty(Q)){
        DeQueue(Q,p);
        visit(p);
        if(p->lchild!=NULL)
            EnQueue(Q,p->lchild);
        if(p->rchild!=NULL)
            EnQueue(Q,p->rchild);
    }
}

/*----------------二叉树的线索化(中序/先序/后序线索化)-------------------*/
//线索二叉树结点
typedef struct ThreadNode{
    ElemType data;
    struct ThreadNode *lchild,*rchild;
    int ltag,rtag;
}ThreadNode,*ThreadTree;

//中序遍历二叉树,一边遍历一边线索化
void visitTT(ThreadNode *q);
void InThread(ThreadTree T){
    if(T!=NULL){
        InThread(T->lchild);
        visitTT(T);
        InThread(T->rchild);
    }
}
void visitTT(ThreadNode *q){
    ThreadNode *pre=NULL;
    if(q->lchild==NULL){
        q->lchild=pre;
        q->ltag=1;
    }
    if(pre!=NULL&&pre->rchild==NULL){
        pre->rchild=q;
        pre->rtag=1;
    }
    pre=q;
}

//先序线索化中,当ltag==0时,才能对左子树先序线索化。
//后序线索化类似。

/*!----------------线索二叉树---------------------找前驱/后继------------------------*/
//!中序线索二叉树找中序后继
//1.找到以P为根的子树中,第一个被中序遍历的结点
ThreadNode *Firstnode(ThreadNode *p){
    //循环找到最左下结点(不一定是叶结点)
    while (p->ltag==0) p=p->lchild;
    return p;
}
//2.在中序线索二叉树中找到结点P的后继结点
ThreadNode *Nextnode(ThreadNode *p){
    //右子树中最左下结点
    if(p->rtag==0) return Firstnode(p->rchild);
    else return p->rchild;       //rtag==1直接返回后继线索
}
//3.对中序线索二叉树进行中序遍历(利用线索实现的非递归算法)!!空间复杂度为O(1)
void Inorder(ThreadNode *T){
    for(ThreadNode *p=Firstnode(T);p!=NULL;p=Nextnode(p))
        visit(p);
}

//!中序线索二叉树找中序前驱
//1.找到以P为根的子树中,最后一个被中序遍历的结点
ThreadNode *Lastnode(ThreadNode *p){
   //循环找到最右下结点(不一定是叶结点)
    while (p->rtag==0) p=p->rchild;
    return p;
}
//2.在中序线索二叉树中找到结点P的前驱结点
ThreadNode *Prenode(ThreadNode *p){
    //左子树中最右下结点
    if(p->ltag==0) return Lastnode(p->lchild);
    else return p->lchild;       //ltag==1直接返回前驱线索
}
//3.对中序线索二叉树进行逆向中序遍历(利用线索实现的非递归算法)!!空间复杂度为O(1)
void RevInorder(ThreadNode *T){
    for(ThreadNode *p=Lastnode(T);p!=NULL;p=Prenode(p))
        visit(p);
}

/*---------------------二叉排序树----------------*/
//二叉排序树结点
typedef struct BSTNode{
    int key;
    struct BSTNode *lchild,*rchlid;
}BSTNode,*BSTree;

//二叉排序树的查找(查找值为key的结点)
BSTNode *BST_Search(BSTree T,int key){
    while(T!=NULL&&key!=T->key){
        if(key<T->key) T=T->lchild;
        else T=T->rchild;
    }
    return T;
}

//插入操作(在二叉排序树中插入关键字为k的新结点)       递归方式,最坏空间复杂度高O(h),执行效率低,不好!!
int BST_Insert(BSTree &T,int k){
    if(T==NULL){
        T=(BSTree)malloc(sizeof(BSTNode));
        T->key=k;
        T->lchild=T->T->rchild=NULL;
        return 1;
    }
    else if(k==T->key)
        return 0;              //!树中存在相同关键字的结点,插入失败
    else if(k<T->key)
        return BST_Insert(T->lchild,k);
    else
        return BST_Insert(T->rchlid,k);
}




int main()
{
    cout << "Hello world!" << endl;
    return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值