数据结构-二叉树及其应用

  • 实验项目名称

二叉树及其应用

  • 实验要求

树是数据结构中应用极为广泛的非线性结构,本单元的实验达到熟悉二叉树的存储结构的特性,以及如何应用树结构解决具体问题。

  • 实验内容

利用二叉树求解表达式的值。

  • 算法分析

void EXTInitStack(ETLinkStack& LS)// 树栈初始化

{

    LS = NULL;

}

void EXTPush(ETLinkStack& LS, ExpTree ET)// 树栈添加元素

{

    ETStackNode* p = new ETStackNode;

    p->ETStackdata = ET;

    p->next = LS;

    LS = p;

}

void EXTPop(ETLinkStack& LS, ExpTree& ET)// 树栈弹出栈顶元素

{

    if (LS == NULL) return;

    ET = LS->ETStackdata;

    ETStackNode* p = LS;

    LS = LS->next;

    delete p;

}

ExpTree EXTGetTop(ETLinkStack& LS)// 树栈获取栈顶元素

{

    if (LS) return LS->ETStackdata;

}

对树栈的相关操作,基本的包括创建栈,添加元素,删除元素,获取栈顶元素。

void ChInitStack(ChLinkStack& CS)// 算符栈初始化

{

    CS = NULL;

}

void ChPush(ChLinkStack& CS, ElemType e)// 算符栈添加元素

{

    ChStackNode* p = new ChStackNode;

    p->ChStackdata = e;

    p->next = CS;

    CS = p;

}

void ChPop(ChLinkStack& CS, ElemType& e)// 算符栈弹出栈顶元素

{

    if (CS == NULL) return;

    e = CS->ChStackdata;

    ChStackNode* p = CS;

    CS = CS->next;

    delete p;

}

ElemType ChGetTop(ChLinkStack& CS)// 算符栈获取栈顶元素值

{

    if (CS != NULL) return CS->ChStackdata;

}

对算符栈的基本操作,包括创建栈,添加元素,删除元素,获取栈顶元素。

bool In(char ch)// 判断ch是否为算符

{

    int i = 0;

    while (Op && Op[i] != ch)

         i++;

    return i < 7;

}

void CreateExpTree(ExpTree& T, TreeNode* lchild, TreeNode* rchild, TreeElemType data)// 创建表达式树结点

{

    T = new TreeNode;

    T->data = data;

    T->lchild = lchild;

    T->rchild = rchild;

}

char Precede(char c1, char c2)// 判断算符优先级

{

    int i = 0, j = 0;

    while (Op[i] && Op[i] != c1)

         i++;

    while (Op[j] && Op[j] != c2)

         j++;

    return CList[i][j];

}

杂项操作,包括判断算符优先级,是否为算符等。

ExpTree InitExpTree()// 表达式树的创建算法

{

    ETLinkStack EXPT;

    ChLinkStack OPTR;

    EXTInitStack(EXPT);

    ChInitStack(OPTR);

    ChPush(OPTR, '=');

    char ch;

    cin >> ch;

    while (ch != '=' || ChGetTop(OPTR) != '=')

    {

         if (!In(ch))

         {

             char data[20] = { '\0' };

             int i = 0;

             data[i++] = ch;

             cin >> ch;

             while (!In(ch))

             {

                  data[i++] = ch;

                  cin >> ch;

             }

             ExpTree T;

             CreateExpTree(T, NULL, NULL, atof(data));

             EXTPush(EXPT, T);

         }

         else

         {

             switch (Precede(ChGetTop(OPTR), ch))

             {

             case '<':

                  ChPush(OPTR, ch);

                  cin >> ch;

                  break;

             case '>':

                  char theta;

                  ChPop(OPTR, theta);

                  TreeNode* t1, * t2;

                  EXTPop(EXPT, t2); EXTPop(EXPT, t1);

                  ExpTree T;

                  CreateExpTree(T, t1, t2, theta);

                  EXTPush(EXPT, T);

                  break;

             case '=':

                  ChPop(OPTR, theta);

                  cin >> ch;

                  break;

             }

         }

    }

    return EXTGetTop(EXPT);

}

创建表达式树:通过算符优先级表得出各算符优先级,时间复杂度O(n)。

double GetValue(char ch, double a, double b)// 求值

{

    switch (ch)

    {

    case '+':

         return a + b;

    case '-':

         return a - b;

    case '*':

         return a * b;

    case '/':

         return a / b;

    }

}

double EvaluateExpTree(ExpTree T)// 遍历表达树进行表达式求值

{

    double lvalue = 0, rvalue = 0;

    if (T->lchild == NULL && T->rchild == NULL)

         return T->data;

    else

    {

         lvalue = EvaluateExpTree(T->lchild);

         rvalue = EvaluateExpTree(T->rchild);

         return GetValue(T->data, lvalue, rvalue);

    }

}

表达式求值:通过后序遍历表达式树得出相应的后缀表达式,之后求值就简单了。

int main()// 主函数

{

    cout << "请输入运算表达式:" << endl;

    ExpTree T = InitExpTree();

    cout << "该运算表达式值为:" << EvaluateExpTree(T) << endl;

    return 0;

}

主函数

  • 实验结果

  • 思考体会

通过树来求表达式比栈复杂一点,但原理很相似,都是通过把一个表达式转化为后缀表达式然后求值,这样求转化后的后缀表达式就简单多了。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

微风-_-

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值