数据结构二叉树的基本操作

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


#ifndef MACRO_//
#define MACRO_
#define OK 1
#define FALSE 0
#define TURE 1
#define ERROR 0
#define OVERFLOW -2
#define INFEASIBLE -1
typedef int Status;
typedef int BOOL;
#endif 

#define ClearTree DestoryBiTree


typedef int TrElemType;//树元素类型


typedef struct BiTNode
{
    TrElemType Data;
    struct BiTNode *Lchild, *Rchild;//左右孩子指针
}BiTNode, *BiTree;

#ifndef STElem_Type_//栈元素类型
#define STElem_Type_
/*typedef struct ST_elem_type//定义栈元素类型,为 树指针类型和BOOL类型(创建BOOL类型是为了非递归后序遍历)
{
BiTree ptr;
BOOL bool_type;
}ST_elem_type;
typedef ST_elem_type STElemType;    //栈元素类型
*/
typedef BiTree STElemType;
#endif 
#include"stack.h"

#ifndef QElem_Type_//队列元素类型
#define QElem_Type_
typedef BiTree QElemType;
#endif 
#include"queue.h"



void InitBiTree(BiTree *T);
//构造空二叉树
Status CreateBiTree(BiTree *T);
//按先序次序输入二叉树结点中的值,空格表示空树
//成功返回OK
Status PreOrderTraverse(BiTree T);
//先序遍历二叉树T的递归算法
Status PreOrderTraverse_General(BiTree T);
//二叉树的非递归先序遍历
Status InOrderTraverse(BiTree T);
//中序遍历二叉树T的递归算法
Status InOrderTraverse_General(BiTree T);
//二叉树的非递归中序遍历
Status PostOrderTraverse(BiTree T);
//后序遍历二叉树T的递归算法
/*
Status PostOrderTraverse_General_one(BiTree T)
//二叉树的非递归后续遍历-----------方法1(需要栈元素类型为结构体)
*/
Status PostOrderTraverse_General_two(BiTree T);
//二叉树的非递归后续遍历-----------方法二(需要栈元素类型为树结点指针)
Status LevelOrdefTraverse(BiTree T);
//二叉树的层序遍历
int Count_NodeNum(BiTree T);
//计算结点数
int Count_Leaf(BiTree T);
//计算叶子结点数
BOOL IsEmpty(BiTree T);
//判断树是否为空
int Count_Deep(BiTree T);
//计算树的深度
TrElemType root(BiTree T);
//返回树的根,如果为空树返回-1
void DestoryBiTree(BiTree *T);/*Destory和Clear操作是相同的*/
//销毁二叉树
TrElemType value(BiTree T, BiTree cur_e);
//树T存在,cur_e是T中某个结点
//返回cur_e的值,如果结点为空或树为空,返回-1
Status Assign(BiTree T, BiTree cur_e, TrElemType *value);
//树T存在,cur_e是T中某个结点
//将cur_e的值赋值为value,成功返回OK,如果结点为空或树为空,返回INFEASEBLE
BiTree Parent(BiTree T, BiTree e);
//二叉树T存在,e是T中某个结点
//若e是T的非根结点,则返回他的双亲,否则返回空
BiTree LeftChild(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的左孩子,若e无左孩子,则返回空
BiTree RightChild(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的右孩子,若e无右孩子,则返回空
BiTree LeftSibling(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的左兄弟,若额是T的左孩子或无做兄弟,则返回空
BiTree RightSibling(BiTree T, BiTree e);
//二叉树存在,e是T中某个结点
//返回e的右兄弟,若e是T的右孩子或无右兄弟,则返回空
Status InsertChild(BiTree T, BiTree p, int LR, BiTree c);
//二叉树T存在,p指向T中某个结点,LR为0或1(0指左,1指右),非空二叉树c与T不相交且右子树为空
//根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左子树或右子树则成为c的右子树
//c有右子树或者p为空返回ERROR,成功返回OK
Status DeleteChild(BiTree T, BiTree p, int LR);
//二叉树T存在,p指向T中某个结点,LR为0或1
//根据LR为0或1,删除T中所指p所指结点的左或右子树
//如果p为空返回ERROR,成功返回OK

/*Input:
ABD  EH   CF IJ   G  |带上空格
The NodeNum is 10
The leaf    is 4
The Deep    is 5
*/

/*Input:
ABD   CE  FG   |带上空格
The NodeNum is 7
The leaf    is 3
The Deep    is 4
*/

int main()
{
    BiTree T,e,test,TestTree;



    printf("Please Enter : ");
    if (CreateBiTree(&T) == OK)
        printf("Creat OK \n");
    printf("\nThe preorder   traversal:  ");
    PreOrderTraverse(T);
    printf("\nThe inorder    traversal:  ");
    InOrderTraverse(T);
    printf("\nThe postorder  traversal:  ");
    PostOrderTraverse(T);
    printf("\nThe levelorder traversal:  ");
    LevelOrdefTraverse(T);
    printf("\nThe Preorder   traversal of General :  ");
    PreOrderTraverse_General(T);

    printf("\nThe inorder    traversal of General :  ");
    InOrderTraverse_General(T);

    printf("\nThe Preorder   traversal of General :  ");
    //PostOrderTraverse_General(T);
    PostOrderTraverse_General_two(T);




    printf("\n/*************test***********/\n");
    TestTree = T->Rchild->Lchild;

    if (test=Parent(T, TestTree))//父节点测试
        printf("\nParent is %c ", test->Data);
    else printf("\nis NULL");

    if (test = LeftChild(T, TestTree))//左孩子测试
        printf("\nLeft is %c ", test->Data);
    else printf("\n no left child");

    if (test = RightChild(T, TestTree))//右孩子测试
        printf("\nLeft is %c ", test->Data);
    else printf("\n no right child");

    if (test = LeftSibling(T, TestTree))//左兄弟测试
        printf("\nLbro is %c", test->Data);
    else printf("\n no left bro");

    if (test = RightSibling(T, TestTree))//右兄弟测试
        printf("\nRbro is %c", test->Data);
    else printf("\n no right bro");
    printf("\n/*************test***********/\n");




    Count_NodeNum(T);
    printf("\nThe NodeNum is %d  ", Count_NodeNum(T));
    printf("\nThe leaf    is %d  ", Count_Leaf(T));
    printf("\nThe Deep    is %d  ", Count_Deep(T));
    IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
    printf("\n/********************test**Insert**Delete*********************/");
    printf("\nPlease Enter : ");//新建树e
    fflush(stdin);
    if (CreateBiTree(&e) == OK)
        printf("Creat OK \n");
    if (InsertChild(T, T->Rchild, 1, e) == OK)
    {
        printf("\n--Ins--\n");
        Count_NodeNum(T);
        printf("\nThe NodeNum is %d  ", Count_NodeNum(T));
        printf("\nThe leaf    is %d  ", Count_Leaf(T));
        printf("\nThe Deep    is %d  ", Count_Deep(T));
        IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
        printf("\nThe levelorder traversal:  ");
        LevelOrdefTraverse(T);
    }//if
    if (DeleteChild(T, T->Rchild, 1) == OK)
    {
        printf("\n--Del--\n");
        Count_NodeNum(T);
        printf("\nThe NodeNum is %d  ", Count_NodeNum(T));
        printf("\nThe leaf    is %d  ", Count_Leaf(T));
        printf("\nThe Deep    is %d  ", Count_Deep(T));
        IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
        printf("\nThe levelorder traversal:  ");
        LevelOrdefTraverse(T);
    }


    printf("\n/********************test**Insert**Delete*********************/");

    DestoryBiTree(&T);//Destory和Clear效果相同,T和结点都会被释放,被赋值为NULL
    printf("\nThe NodeNum is %d  ", Count_NodeNum(T));
    printf("\nThe leaf    is %d  ", Count_Leaf(T));
    printf("\nThe Deep    is %d  ", Count_Deep(T));
    IsEmpty(T) ? printf("\nIsEmpty") : printf("\nNoEmpty");
    system("pause");
}

void InitBiTree(BiTree *T)
//构造空二叉树
{
    T = NULL;
}//InitBiTree

Status CreateBiTree(BiTree *T)
//按先序次序输入二叉树结点中的值,空格表示空树
//成功返回OK
{
    char ch = getchar();
    if (ch == ' ')
        *T = NULL;
    else
    {
        (*T) = (BiTree)malloc(sizeof(BiTNode));
        if (!(*T))exit(OVERFLOW);
        (*T)->Data = ch;
        CreateBiTree(&(*T)->Lchild);//构造左子树
        CreateBiTree(&(*T)->Rchild);//构造右子树
    }//else
    return OK;
}//CreateBiTree

void DestoryBiTree(BiTree *T)
//销毁二叉树
{
    if (*T)
    {
        if ((*T)->Lchild)
            DestoryBiTree(&(*T)->Lchild);
        if ((*T)->Rchild)
            DestoryBiTree(&(*T)->Rchild);
        free(*T);
        (*T) = NULL;
    }//if
}//DestoryBiTree

Status PreOrderTraverse(BiTree T)
//采用二叉链表存储结构
//先序遍历二叉树T的递归算法
{
    BiTree P = T;
    if (P)
    {
        printf("%c", P->Data);
        PreOrderTraverse(P->Lchild);
        PreOrderTraverse(P->Rchild);
    }//if
    return OK;
}//PreOrderTraverse

Status PreOrderTraverse_General(BiTree T)
//二叉树的非递归先序遍历
{
    SLinkStack S;
    Init_Stack(&S);
    STElemType q, p;//栈中元素是结构体
    p = T;//p从头到尾只被当成指针,没使用过其BOOL值
    while (StackEmpty(S) != TURE || p)
    {
        if (p)
        {
            printf("%c", p->Data);
            push(S, p);
            p = p->Lchild;
        }//if
        else
        {
            pop(S, &q);
            p = q->Rchild;
        }//else
    }//while
    DestoryStack(&S);
    return OK;
}//PreOrderTraverse_General

Status InOrderTraverse(BiTree T)
//采用二叉链表存储结构
//中序遍历二叉树T的递归算法
{
    BiTree P = T;
    if (P)
    {
        InOrderTraverse(P->Lchild);
        printf("%c", P->Data);
        InOrderTraverse(P->Rchild);
    }//if
    return OK;
}//InOrderTraverse

Status InOrderTraverse_General(BiTree T)
//二叉树的非递归中序遍历
{
    SLinkStack S;
    Init_Stack(&S);
    STElemType q, p;//栈中元素是结构体
    p = T;         //p从头到尾只被当成指针,没使用过其BOOL值(如果将栈元素类型当成结构体)
    while (StackEmpty(S) != TURE || p)
    {
        if (p)
        {
            push(S, p);
            p = p->Lchild;
        }//if
        else
        {
            pop(S, &q);
            p = q;
            printf("%c", p->Data);
            p = p->Rchild;
        }//else
    }//while
    DestoryStack(&S);
    return OK;
}//InOrderTraverse_General

Status PostOrderTraverse(BiTree T)
//采用二叉链表存储结构
//后序遍历二叉树T的递归算法
{
    BiTree P = T;
    if (P)
    {
        PostOrderTraverse(P->Lchild);
        PostOrderTraverse(P->Rchild);
        printf("%c", P->Data);
    }//if
    return OK;
}//PostOrderTraverse

/*Status PostOrderTraverse_General_one(BiTree    T)
//二叉树的非递归后续遍历-----------方法1(需要栈元素类型为结构体)
{
SLinkStack S;
Init_Stack(&S);
STElemType p, q;
p.ptr = T;//p从头到尾只被当成指针,没使用过其BOOL值
while (StackEmpty(S)!=TURE||p.ptr)
{
if (p.ptr)
{
p.bool_type = FALSE;//做标志,没有被访问过
push(S, p);
p.ptr = p.ptr->Lchild;//访问左孩子
}//if
else
{
GetTop(S, &q);//取栈顶元素
if (q.bool_type == FALSE)//如果栈顶元素BOOL值为FASLE,说明栈顶元素还未被访问过->(当前为左孩子回溯),接下来要访问他的右孩子
{
p.ptr = q.ptr->Rchild;//访问该结点的右孩子
S->next->data.bool_type = TURE;//修改当前BOOL类型,已经被访问
}//if
else//否则BOOL值为TURE,说明已经被访问过->当前为右孩子回溯
{
pop(S, &q);
printf("%c", q.ptr->Data);
}//else
}//else
}//while
DestoryStack(&S);
return OK;
}//PostOrderTraverse_General
*/

Status PostOrderTraverse_General_two(BiTree T)
//二叉树的非递归后续遍历-----------方法二(需要栈元素类型为树结点指针)
{
    SLinkStack S;
    Init_Stack(&S);
    STElemType p, q, r;
    p = T;
    while (StackEmpty(S) != TURE || p)
    {
        if (p)
        {
            push(S, p);
            push(S, p);
            p = p->Lchild;
        }//if
        else
        {
            pop(S, &q);
            if (StackEmpty(S) == TURE)
            {
                printf("%c", q->Data);
                continue;
            }//if
            else
                GetTop(S, &r);//记录栈顶元素
            if (r == q)//如果栈顶元素等于刚弹出的栈外元素,说明该元素是第一次弹出
                p = q->Rchild;
            else
                printf("%c", q->Data);
        }//else
    }//while
    return OK;
}//PostOrderTraverse_General_two

Status LevelOrdefTraverse(BiTree T)
//二叉树的层序遍历
{
    LinkQueue Q;
    InitQueue(&Q);//初始化队列
    QElemType e;//队列元素类型为BiTree
    Enqueue(&Q, T);
    while (QueueEmpty(Q) != TURE)
    {
        Dequeue(&Q, &e);
        if (e)
        {
            printf("%c", e->Data);
            if (e->Lchild)
                Enqueue(&Q, e->Lchild);
            if (e->Rchild)
                Enqueue(&Q, e->Rchild);
        }//if
    }//while
    DestoryQueue(&Q);
    return OK;
}//LevelOrdefTraverse

int Count_NodeNum(BiTree T)
//计算结点数
{
    if (T)
        return Count_NodeNum(T->Lchild) + Count_NodeNum(T->Rchild) + 1;//结点数为左子树结点数+右子树结点数+1
    return 0;
}//Count_NodeNum

int Count_Leaf(BiTree T)
//计算叶子结点数
{
    if (!T)
        return 0;
    else if (!T->Lchild&&!T->Rchild)
        return 1;
    else
        return Count_Leaf(T->Lchild) + Count_Leaf(T->Rchild);//叶子结点数为左子树中叶子节点数+右子树中叶子结点数
}//Count_Leaf

int Count_Deep(BiTree T)
//计算树的深度
{
    if (T)
        return (Count_Deep(T->Lchild) > Count_Deep(T->Rchild) ? Count_Deep(T->Lchild) : Count_Deep(T->Rchild)) + 1; //深度为max(左子树深度,右子树深度)+1
    return 0;
}//Count_Deep

BOOL IsEmpty(BiTree T)
//判断树是否为空
{
    return !T ? TURE : FALSE;
}//IsEmpty

TrElemType root(BiTree T)
//返回树的根,如果为空树返回-1
{
    if (IsEmpty(T) == TURE)
        return -1;
    return T->Data;
}//root

TrElemType value(BiTree T, BiTree cur_e)
//树T存在,cur_e是T中某个结点
//返回cur_e的值,如果结点为空或树为空,返回-1
{
    if (T&&cur_e)
        return cur_e->Data;
    else return -1;
}//value

Status Assign(BiTree T, BiTree cur_e, TrElemType *value)
//树T存在,cur_e是T中某个结点
//将cur_e的值赋值为value,成功返回OK,如果结点为空或树为空,返回INFEASEBLE
{
    if (T&&cur_e)
    {
        (*value) = cur_e->Data;
        return OK;
    }//if
    else return INFEASIBLE;
}//Assign

BiTree Parent(BiTree T,BiTree e)
//二叉树T存在,e是T中某个结点
//若e是T的非根结点,则返回他的双亲,否则返回空
{
    if (NULL == e || e == T)//如果e为根结点或者e为NULL
        return NULL;
    LinkQueue Q;
    QElemType Qelem=NULL;
    InitQueue(&Q);//建立队列
    Enqueue(&Q, T);//头结点入队
    do
    {
        Dequeue(&Q, &Qelem);
        if (Qelem->Lchild)//左孩子不为空,入队
            Enqueue(&Q, Qelem->Lchild);
        if (Qelem->Rchild)//右孩子不会空,入队
            Enqueue(&Q, Qelem->Rchild);
    }//do
    while ((QueueEmpty(Q) != TURE) && (Qelem->Rchild != e) && (Qelem->Lchild != e)); //队列不空 && 左孩子不为e && 右孩子不为e
    if (Qelem->Rchild == e || Qelem->Lchild == e)
        return Qelem;
    else return NULL;
}//Parent

BiTree LeftChild(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的左孩子,若e无左孩子,则返回空
{
    return e ? e->Lchild : NULL;
}//LeftChild

BiTree RightChild(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的右孩子,若e无右孩子,则返回空
{
    return e ? e->Rchild : NULL;
}//LeftChild

BiTree LeftSibling(BiTree T,BiTree e)
//二叉树存在,e是T中某个结点
//返回e的左兄弟,若额是T的左孩子或无做兄弟,则返回空
{
    BiTree parent = Parent(T,e);
    if (parent)
        return (e == parent->Lchild) ? NULL : parent->Lchild;//e如果是左孩子,返回NULL,如果不是,返回左孩子(左孩子也可能为NULL)
    else return NULL;//parent为空说明e没有父结点或者e为空
}//LeftSibling

BiTree RightSibling(BiTree T, BiTree e)
//二叉树存在,e是T中某个结点
//返回e的右兄弟,若e是T的右孩子或无右兄弟,则返回空
{
    BiTree parent = Parent(T, e);
    if (parent)
        return (e == parent->Rchild )? NULL : parent->Rchild;//e如果是右孩子,返回NULL,如果不是,返回右孩子(右孩子也可能为NULL)
    else return NULL;//parent为空说明e没有父结点或者e为空
}//RightSibling

Status InsertChild(BiTree T, BiTree p, int LR, BiTree c)
//二叉树T存在,p指向T中某个结点,LR为0或1(0指左,1指右),非空二叉树c与T不相交且右子树为空
//根据LR为0或1,插入c为T中p所指结点的左或右子树。p所指结点的原有左子树或右子树则成为c的右子树
//c有右子树或者p为空返回ERROR,成功返回OK
{
    if (c->Rchild||!p)
        return ERROR;
    if (0 == LR)//插入左边
    {
        c->Rchild = p->Lchild;
        p->Lchild = c;
    }//if
    else
    {
        c->Rchild = p->Rchild;
        p->Rchild = c;
    }//else
    return OK;
}//InsertChild

Status DeleteChild(BiTree T,BiTree p,int LR)
//二叉树T存在,p指向T中某个结点,LR为0或1
//根据LR为0或1,删除T中所指p所指结点的左或右子树
//如果p为空返回ERROR,成功返回OK
{
    if (p)
    {
        if (0 == LR)
            DestoryBiTree(&p->Lchild);
        else
            DestoryBiTree(&p->Rchild);
        return OK;
    }//if
    return ERROR;
}//DeleteChild

 

posted @ 2018-09-01 14:00  散装英语king  阅读(434)  评论(0)    收藏  举报