数据结构——二叉树的建立、遍历、求度数、深度

二叉树的建立直接用递归操作即可

二叉树的遍历有三种

  • 先序遍历DLR:根节点->左子树->右子树
  • 中序遍历LDR:左子树->根节点->右子树。必须要有中序遍历才能得到一棵二叉树的正确顺序
  • 后续遍历LRD:左子树->右子树->根节点。需要栈的支持。
  • 特殊的遍历方法就是层次遍历,即按照二叉树每一层打印

获取叶子数目

    直接判断每个节点的下一结点是否为空即可

求二叉树的深度

    用递归算法分别求二叉树的左右子树的深度,取最大值

求二叉树的度数

设置num为全局变量,即每次遍历一个结点,num加1

#include <stdio.h>
#include <stdlib.h>

#define MAXSIZE 100

//二叉树
typedef struct node{
    char data;//数据域
    struct node *lchild,*rchild;//指针域
}BinTree;

//线索二叉树
typedef struct ThreadTNode{
    int lTag,rTag;//左右标志域
    char data;//数据域
    struct ThreadTNode *lchild,*rchild;//左右孩子指针域
}ThreadTNode,*ThreadTree;

//创建普通二叉树
BinTree *creatTree()
{
    BinTree *Tree = NULL;
    char ch;
    ch = getchar();//输入一个字符
    if(ch != '#')
    {
        Tree = (BinTree*)malloc(sizeof(BinTree));//分配空间
        Tree->data = ch;
        Tree->lchild = creatTree();//创建左子树
        Tree->rchild = creatTree();//创建右子树
    }
    return Tree;
}

/*先序遍历二叉树*/
void preorder(BinTree *Tree)
{
    if(Tree)//二叉树不为空
    {
        printf("%c",Tree->data);//输出节点的值
        preorder(Tree->lchild);//遍历左子树
        preorder(Tree->rchild);//遍历右子树
    }
}

/*中序遍历二叉树*/
void inorder(BinTree *Tree)
{
    if(Tree)//二叉树不为空
    {
        inorder(Tree->lchild);//遍历左子树
        printf("%c",Tree->data);//输出节点的值
        inorder(Tree->rchild);//遍历右子树
    }
}

/*后序遍历二叉树*/
void postorder(BinTree *Tree)
{
    if(Tree)//二叉树不为空
    {
        postorder(Tree->lchild);//遍历左子树
        postorder(Tree->rchild);//遍历右子树
        printf("%c",Tree->data);//输出节点的值
    }
}

/*中序输出二叉树非递归算法*/
void inorderTraverse(BinTree *bt)
{
    BinTree *stack[MAXSIZE],*p;//定义顺序栈stack,最大值为100
    int top = 0;//定义栈顶指针
    p = bt;
    do
    {
        while(p != NULL)//顺着左链搜索到尽头
        {
            stack[top++] = p;//当二叉树不为空时根指针入栈
            p = p->lchild;//顺着左链搜索
        }
        if(top > 0)
        {
            p = stack[top-1];//栈不为空时取出栈顶元素
            printf("%c",stack[top-1]->data);//输出当前访问的根节点
            top--;
            p = p->rchild;//顺着右链搜索
        }
    }
    while(top != 0||p != NULL);//当遍历没有结束时继续访问
}

/*获取叶子数目*/
void getLeafNumber(BinTree *T,int *count)
{
    if(T)
    {
        if((!T->lchild)&&(!T->rchild))//左右孩子都为空
        {
            (*count)++;//对叶子数目计数
        }
        getLeafNumber(T->lchild,count);
        getLeafNumber(T->rchild,count);
    }
}

/*获取二叉树的深度*/
int getDepth(BinTree *T)
{
    int higthLeft,highRight;
    if(!T)
        return 0;
    else
    {
        higthLeft = getDepth(T->lchild);
        highRight = getDepth(T->rchild);
        if(higthLeft >= highRight)
            return higthLeft+1 ;
        else
            return highRight+1 ;
    }
}

/*创建线索二叉树的中序线索链表*/
ThreadTree pre;//pre定义全局变量,始终指向当前节点的前驱
ThreadTree inorderThread(ThreadTree bt)
{
    ThreadTree head;//建立二叉树bt的中序线索链表
    head = (ThreadTree)malloc(sizeof(ThreadTNode));
    if(head)
    {
        printf("分配内存错误\n");
        return NULL;
    }
    head->lTag = 0; head->rTag = 1;//设置头结点的线索标志域
    head->rchild = head;//头结点右指针指向自身
    if(bt == NULL)
        head->lchild = head;//若二叉树bt为空,左线索指向自身
    else
    {
        head->lchild = head;//若二叉树非空则左线索指向二叉树根节点bt处
        pre = head;//pre指向当前节点的前驱
        inorderThread(bt);//中序遍历进行中序线索化
        pre->rchild = head;//最后一个节点右线索化
        pre->rTag = 1;//最后一个节点标志域置为线索
        pre->rchild = pre;//头结点的右指针指向最后一个节点
    }
    return head;
}


int main()
{
    int number = 0;
    BinTree *T = creatTree();
    printf("先序遍历二叉树结果\n");
    preorder(T);
    printf("\n");
    printf("中序遍历二叉树结果\n");
    inorder(T);
    printf("\n");
    printf("后序遍历二叉树结果\n");
    postorder(T);
    printf("\n");
    printf("中序输出二叉树非递归算法\n");
    inorderTraverse(T);
    printf("\n");
    printf("获取叶子数目\n");
    getLeafNumber(T,&number);
    printf("%d",number);
    printf("\n");
    printf("获取二叉树的深度\n");
    printf("%d",getDepth(T));
    printf("\n");
    //ThreadTNode *T;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/weixin_42562514/article/details/84975125