二叉树的基本操作

头文件:
BStack.h


#ifndef _BSTACK__H_
#define _BSTACK__H_

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

#define MAX_SIZE 20
typedef char* Datatype;
//typedef int Datatype;

typedef struct Stack{
    Datatype _data[MAX_SIZE];
    int _size;
}Stack, *S;

void StackInit(S ps);//初始化
void Stackpushback(S ps,Datatype data);//尾插(入栈)
void Stackpopback(S ps);//尾删(出栈)
char  *Stacktop(S ps);//查看栈顶元素
int  Empty(S ps);//是否为空

BinTree.h

#ifndef _BINTREE__H_
#define _BINTREE__H_


#include<assert.h>
#include<string.h>
#include<stdio.h>
#include<stdlib.h>
#include<malloc.h>
#include<Windows.h>
#include<math.h>


//函数顺序!!!
typedef char DataType;

typedef struct  BinTreeNode
{
    struct BinTreeNode* _pleft;
    struct BinTreeNode* _pright;
    DataType _data; 
}Node, *PNode;

PNode BuyNode(DataType data);             //创建节点
void CreateBinTree(PNode* pRoot, DataType* array, int size, DataType invalid);// 创建二叉树 
void _CCreateBinTree(PNode* pRoot, DataType* array, int size, int* index, DataType invalid);
PNode CopyBinTree(PNode pRoot);           // 拷贝
void Destroy(PNode* pRoot);               //销毁
void PreOrder(PNode pRoot);               //前序遍历
void InOrder(PNode pRoot);                //中序遍历
void PostOrder(PNode pRoot);              //后序遍历
int Size(PNode pRoot);                    //二叉树节点个数
int GetLeafCount(PNode pRoot);            //获取叶子节点树
int Height(PNode pRoot);                  //树的高度
int GetKlevel(PNode pRoot, int K);        //第K层节点个数
void Mirror(PNode pRoot);                 //镜像树
PNode Find(PNode pRoot, DataType data);   //查找数据                                         
PNode LeftChild(PNode pNode); // 获取当前节点的左孩子 
int IsNodeInBinTree(PNode pRoot, PNode pNode);  // 判断一个节点是否在二叉树中 
void IsFullBinTree(PNode pRoot);// 判断一棵树是否是满二叉树 
PNode RightChild(PNode pNode);// 获取当前节点的右孩子
//int IsCompleteBinTree(PNode pRoot);     // 判断一棵树是否是完全二叉树 
void PreOrderNor(PNode pRoot);            // 前序非递归
void InOrderNor(PNode pRoot);             // 中序非递归 
void PostOrder_Nonrecursive(pRoot);           // 后序非递归 

#endif // !_BINTREE__H_

源文件
BStack.c


#include "BStack.h"

void StackInit(S ps)
{
    assert(ps);
    ps->_size = 0;
    memset(ps->_data, 0, sizeof(ps->_data));
}

void Stackpushback(S ps, Datatype data)
{
    assert(ps);
    if (ps->_size == MAX_SIZE)
    {
        return;
    }
    ps->_data[ps->_size] = data;
    ps->_size++;
}

void Stackpopback(S ps)
{
    assert(ps);
    if (ps->_size == 0)
    {
        return;
    }
    ps->_size--;
}

char  *Stacktop(S ps)
{
    assert(ps);
    return (ps->_data[ps->_size - 1]);
}

int  Empty(S ps)
{
    assert(ps);
    if (ps->_size == 0)
        return 1;
    else
        return 0;
}

BinTree.c


#include "BinTree.h"
#include "BStack.h"


PNode BuyNode(DataType data)
{
    PNode pnew = (PNode)malloc(sizeof(Node));
    assert(pnew);
    pnew->_data = data;
    pnew->_pleft = NULL;
    pnew->_pright = NULL;
    return pnew;
}
/


void _CCreateBinTree(PNode* pRoot, DataType* array, int size, int* index, DataType invalid)
{
    assert(index);
    if (*index < size && invalid != array[*index])
    {
        *pRoot = BuyNode(array[*index]);

        ++(*index);
        _CCreateBinTree(&(*pRoot)->_pleft, array, size, index, invalid);

        ++(*index);
        _CCreateBinTree(&(*pRoot)->_pright, array, size, index, invalid);
    }
}

void CreateBinTree(PNode* pRoot, DataType* array, int size, DataType invalid)
{
    int index = 0;
    _CCreateBinTree(pRoot, array, size, &index, invalid);
}

PNode CopyBinTree(PNode pRoot)
{
    PNode pnewRoot = NULL;
    if (pRoot)
    {
        pnewRoot = BuyNode(pRoot->_data);

        pnewRoot->_pleft = CopyBinTree(pRoot->_pleft);

        pnewRoot->_pright = CopyBinTree(pRoot->_pright);
    }
    return pnewRoot;
}

void PreOrder(PNode pRoot)//前序遍历
{
    if (pRoot)
    {
        printf("%c ", pRoot->_data);

        PreOrder(pRoot->_pleft);

        PreOrder(pRoot->_pright);
    }
}
void InOrder(PNode pRoot)//中序遍历
{
    if (pRoot)
    {
        InOrder(pRoot->_pleft);

        printf("%c ", pRoot->_data);

        InOrder(pRoot->_pright);
    }
}
void PostOrder(PNode pRoot)//后序遍历
{
    if (pRoot)
    {
        PostOrder(pRoot->_pleft);

        PostOrder(pRoot->_pright);

        printf("%c ", pRoot->_data);
    }
}

int Size(PNode pRoot)
{
    if (NULL == pRoot)
        return 0;
    return (Size(pRoot->_pleft) + Size(pRoot->_pright) + 1);
}

int GetLeafCount(PNode pRoot)
{
    if (NULL == pRoot)
        return 0;
    if (NULL == pRoot->_pleft && NULL == pRoot->_pright)
        return 1;
    return GetLeafCount(pRoot->_pleft) + GetLeafCount(pRoot->_pright);
}

void Destroy(PNode* pRoot)//后序销毁
{
    assert(pRoot);
    if (pRoot)
    {
        Destroy(&(*pRoot)->_pleft);
        Destroy(&(*pRoot)->_pright);
        free(*pRoot);
        *pRoot = NULL;
    }
}

int Height(PNode pRoot) //树高度
{
    int leftHeight = 0;
    int rightHeight = 0;
    if (NULL == pRoot)
        return 0;
    leftHeight = Height(pRoot->_pleft);
    rightHeight = Height(pRoot->_pright);

    return leftHeight > rightHeight ? leftHeight + 1 : rightHeight + 1;
}

int GetKlevel(PNode pRoot, int K)    //第K层节点个数
{
    if (NULL == pRoot || K <= 0)
        return 0;
    if (K == 1)
        return 1;
    return GetKlevel(pRoot->_pleft, K - 1) + GetKlevel(pRoot->_pright, K - 1);
}

void Mirror(PNode pRoot)
{
    if (pRoot)
    {
        PNode p = pRoot->_pleft;
        pRoot->_pleft = pRoot->_pright;
        pRoot->_pright = p;

        Mirror(pRoot->_pleft);
        Mirror(pRoot->_pright);
    }
}

PNode Find(PNode pRoot, DataType data)
{
    PNode pnode = NULL;
    if (pRoot == NULL)
        return NULL;

    if (pRoot->_data == data)
        return pRoot;

    if (pnode = Find(pRoot->_pleft, data))
        return pnode;

    return Find(pRoot->_pright, data);
}

PNode LeftChild(PNode pNode) // 获取当前节点的左孩子 
{
    if (pNode == NULL)
        return NULL;
    return (pNode->_pleft);
}

PNode RightChild(PNode pNode)// 获取当前节点的右孩子 
{
    if (pNode == NULL)
        return NULL;
    return (pNode->_pright);
}

int IsNodeInBinTree(PNode pRoot, PNode pNode)  //判断一个节点是否在二叉树中 
{
    if (NULL == pNode)
        return 0;
    if (NULL == Find(pRoot, pNode->_data))
        return 0;
    else
        return 1;
}

//int IsCompleteBinTree(PNode pRoot)// 判断一棵树是否是完全二叉树 
//{
//
//}
void IsFullBinTree(PNode pRoot)// 判断一棵树是否是满二叉树 
{
    int count = GetLeafCount(pRoot);
    int k = Height(pRoot);
    if (pow(2, (k - 1)) == count)
    {
        printf("是满二叉树\n");
    }
    else
        printf("不是满二叉树\n");
}

void PreOrderNor(PNode pRoot)   // 前序非递归 
{

    Stack s;
    StackInit(&s);
    if (NULL == pRoot)
    {
        printf("空树");
        return;
    }
    while (pRoot || !Empty(&s))
    {
        while (pRoot)
        {
            Stackpushback(&s, pRoot);
            printf("%c ", pRoot->_data);
            pRoot = pRoot->_pleft;
        }
        pRoot = Stacktop(&s);
        Stackpopback(&s);
        pRoot = pRoot->_pright;
    }
}

void InOrderNor(PNode pRoot)  // 中序非递归
{
    Stack s;
    StackInit(&s);
    if (!pRoot)
    {
        printf("空树!\n");
        return;
    }
    while (pRoot || !Empty(&s))
    {
        while (pRoot)
        {
            Stackpushback(&s, pRoot);
            pRoot = pRoot->_pleft;
        }
        pRoot = Stacktop(&s);
        Stackpopback(&s);
        printf("%c ", pRoot->_data);
        pRoot = pRoot->_pright;
    }
}


/* 非递归后序遍历二叉树 */
void  PostOrder_Nonrecursive(PNode pRoot)
{
    Stack s;
    StackInit(&s);
    PNode ppre = NULL;
    //判空
    if (NULL == pRoot)
    {
        printf("空树\n");
        return;
    }
    while (pRoot || !Empty(&s))
    {
        //压栈
        while (pRoot)
        {
            Stackpushback(&s, pRoot);
            pRoot = pRoot->_pleft;
        }
        //取栈顶元素
        pRoot = Stacktop(&s);
        //如果无右节点或右节点被访问过,访问该节点
        if (pRoot->_pright == NULL || pRoot->_pright == ppre)
        {
            printf("%c ", pRoot->_data);
            Stackpopback(&s);
            ppre = pRoot;
            pRoot = NULL;              //pRoot要设为NULL,不然程序不会中止
        }
        else
        {
            pRoot = pRoot->_pright;  //如果该节点的右子树没被访问过且不为空,处理他的右子树
        }
    }
}


void TestBinTree()
{
    char* pstr = "ABD###CE##F";
    PNode pRoot = NULL;
    PNode pnewRoot = NULL;
    PNode pRight = NULL;
    int ret = 0;

    CreateBinTree(&pRoot, pstr, strlen(pstr), '#');//创建
    pnewRoot = CopyBinTree(pRoot);
    PreOrder(pRoot);                               //前序递归
    printf("\n");
    InOrder(pRoot);                                //中序递归
    printf("\n");
    PostOrder(pRoot);                              //后序递归
    printf("\n");
    printf("%d ", Size(pRoot));                    //节点数
    printf("\n");
    pRight = RightChild(Find(pRoot, 'C'));
    printf("%c", pRight->_data);                   //获取右孩子
    printf("\n");
    IsFullBinTree(pRoot);                          //是否满二叉树
    ret = IsNodeInBinTree(pRoot, Find(pRoot, 'F'));
    printf("%d", ret);
    printf("\n");
    PreOrderNor(pRoot);                           //前序非递归
    printf("\n");
    InOrderNor(pRoot);                            //中序非递归
    printf("\n");
    PostOrder_Nonrecursive(pRoot);                //后序非递归
    printf("\n");
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值