C++创建二叉树及一些相关算法

C++创建二叉树及一些相关算法

#include<iostream>
using namespace std;
#include<string>
#include<stack>
#include<queue>

//二叉树相关代码总结

//二叉树节点定义
typedef char ElemType;
struct BinaryNode
{
	ElemType data;
	BinaryNode *Lchild, *Rchild;
};

typedef BinaryNode* tree;

void PrintBinaryNodeData(tree & T)
{
    cout << T->data;
}

//前序创建二叉树
void CreatBiTree(tree &T) 
{
	char ch;
    cin >> ch;
    if (ch == '#')//输入#代表T为空节点
    {
        T = NULL;
    }
    else
    {
        T = new BinaryNode;
        T->data = ch;
        CreatBiTree(T->Lchild);
        CreatBiTree(T->Rchild);
    }    
}

//前序遍历二叉树
void PreOrderTraverse(tree &T)
{
    if (T == NULL)
    {
        return;
    }
    cout << T->data;
    PreOrderTraverse(T->Lchild);
    PreOrderTraverse(T->Rchild);
}

//中序遍历
void InOrderTraverse(tree &T)
{
    if (T == NULL)
    {
        return;
    }
    else
    {
        InOrderTraverse(T->Lchild);
        cout << T->data;
        InOrderTraverse(T->Rchild);
    }
    
}

//后序遍历
void PostOrderTraverse(tree &T)
{
    if (T == NULL)
    {
        return;
    }
    else
    {
        PostOrderTraverse(T->Lchild);
        PostOrderTraverse(T->Rchild);
        cout << T->data;
    }
    
}

//二叉树的前序遍历——非递归算法
// void DLR(tree &T)
// {
//     /*错误写法, T是二重指针,该函数修改T,
//     实际会修改T指向的root指针指向的地址,导致循环后root值为NUll 
//     */
//     stack<tree> s;
//     while (T || !s.empty())
//     {
//         if (T)
//         {
//             s.push(T);
//             PrintBinaryNodeData(T);
//             T = T->Lchild;
//         }
//         else
//         {
//             T = s.top();
//             s.pop();
//             T = T->Rchild;
//         }
//     }
// }

//二叉树的前序遍历——非递归算法(正确写法)
void DLR(tree &T)
{
    /*该函数的p是一重指针,实际指向的是T指向的root指针指向的地址
    */
    stack<tree> s;
    tree p = T;
    // cout << "p is "<< p <<endl;
    // cout << "root is "<< &T <<endl;
    while (p || !s.empty())
    {
        if (p)
        {
            s.push(p);
            PrintBinaryNodeData(p);
            p = p->Lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            p = p->Rchild;
        }
    }    
}

//二叉树的中序遍历——非递归算法
void LDR(tree &T)
{
    stack<tree> s;
    tree p = T;
    while (p || !s.empty())
    {
        if (p)
        {
            s.push(p);
            p = p->Lchild;
        }
        else
        {
            p = s.top();
            s.pop();
            PrintBinaryNodeData(p);
            p = p->Rchild;
        }
        
    }
    
}

//二叉树的后序遍历——非递归算法
//辅助栈实现
void LRD(tree & T)
{
    stack<tree> A;
    stack<tree> B;
    tree p = T;
    A.push(p);
    while (!A.empty())
    {
        p = A.top();
        A.pop();
        B.push(p);
        if(p->Lchild)
        {
            A.push(p->Lchild);
        }
        if (p->Rchild)
        {
            A.push(p->Rchild);
        }   
    }
    while (!B.empty())
    {
        p = B.top();
        B.pop();
        PrintBinaryNodeData(p);
    }
}

//二叉树的层次遍历
void LevelOrder(tree &T)
{
    /*
    算法设计思路:
    1.将根结点入队
    2.队列不为空时循环,从队列中出列一个元素,访问它,并作以下步骤:
        2.1 如果该元素的左孩子不为空,让该元素的左孩子入队
        2.2 如果该元素的右孩子不为空,让该元素的右孩子入队
    */
    queue<tree> q;
    tree p = T;
    q.push(p);
    while (!q.empty())
    {
        p = q.front();
        q.pop();
        PrintBinaryNodeData(p);
        if (p->Lchild)
        {
            q.push(p->Lchild);
        }
        if (p->Rchild)
        {
            q.push(p->Rchild);
        }
    }
}

//二叉树的复制-利用先序遍历实现
void CopyBinary(tree &T, tree &NewT)
{
    if(T == NULL)
    {
        NewT = NULL;
        return;
    }
    else
    {
        NewT = new BinaryNode;
        NewT->data = T->data;
        CopyBinary(T->Lchild, NewT->Lchild);
        CopyBinary(T->Rchild, NewT->Rchild);
    }
}

//计算二叉树的深度
int Depth(tree T)
{
    if(T == NULL)
    {
        return 0;//空树返回0
    }
    else
    {
        int m = Depth(T->Lchild);
        int n = Depth(T->Rchild);
        if (m > n) return (m+1);
        else return (n+1);
    }
}

//计算二叉树的节点数
int CountNode(tree T)
{
    if (T == NULL)
    {
        return 0;
    }
    return CountNode(T->Lchild) + CountNode(T->Rchild) +1;
}

//二叉树的叶子节点数
int LeadCount(tree T)
{
    if (T == NULL)
    {
        return 0;
    }
    if (T->Lchild == NULL && T->Rchild == NULL)
    {
        return 1;
    }
    return LeadCount(T->Lchild) + LeadCount(T->Rchild);
}

int main()
{
    BinaryNode *root = NULL;
    CreatBiTree(root);
    PreOrderTraverse(root);
    cout << endl;
    InOrderTraverse(root);
    cout << endl;
    PostOrderTraverse(root);
    cout << endl;
    DLR(root);
    cout << endl;
    LDR(root);
    cout << endl;
    LRD(root);
    cout << endl;
    LevelOrder(root);
    cout << endl;
    BinaryNode *new_root = NULL;
    CopyBinary(root, new_root);
    cout << endl;
    DLR(new_root);
    cout << endl;

    cout << "树的深度为"<< Depth(root) << endl;
    cout << "树的节点数为"<< CountNode(root) << endl;
    cout << "树的y叶子节点数为"<< LeadCount(root) << endl;

	system("pause");

	return 0;
}

代码执行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值