构造一棵表达式二叉树
来源:互联网 发布:linux c 文件路径 编辑:程序博客网 时间:2024/05/22 13:22
下面这个程序是我看weiss的《数据结构与算法分析》的第四章的树里面的一个算法写的程序,具体可以看该书的第一版的71页这个给出我的实现,希望来者给出更加好的设计思路。
程序里面给出了8种遍历方式,欧拉遍历(其实就是中序加了两个括号而已),前序非递归,中序非递归,后序非递归,前序递归,中序递归,后序递归,
另外程序也添加了按层遍历二叉树,程序如下:
- #include <ctype.h>
- #include <malloc.h>
- #include <stdio.h>
- #include <queue>
- using namespace std;
- typedef struct Treenode *ptrtonode;
- typedef ptrtonode Tree;
- struct Treenode {
- char x;
- Tree lefttree;
- Tree righttree;
- } Treenode;
- typedef struct List_Stack {
- struct List_Stack *next;
- Tree mytree;
- } Node, *LS;
- void initstack(LS *a) {
- (*a) = (LS)malloc(sizeof(Node));
- (*a)->next = NULL;
- }
- bool stackempty(const LS a) {
- return a->next == NULL;
- }
- /* 链栈一般不会满,不测试
- bool stackfull(const LS a) {
- return !stackempty(a);
- }
- */
- void push(LS *lstack, Tree a) {
- LS res = (LS)malloc(sizeof(Node));
- res->mytree = a;
- res->next = (*lstack)->next;
- (*lstack)->next = res;
- }
- Tree pop(LS *lstack) {
- if (stackempty(*lstack)) {
- printf("Pop error,stack is empty!/n");
- return NULL;//打印一个笑脸
- }
- LS p = (*lstack)->next;
- Tree x = p->mytree;
- LS pnext = p->next;
- //free(p);
- (*lstack)->next = pnext;
- return x;
- }
- bool isoperator(char a) {
- if(a == '-' || a == '+' || a == '*' || a == '/')
- return 1;
- else
- return 0;
- }
- Tree chartotree(char a) {
- Tree mytree = (Tree)malloc(sizeof(Treenode));
- mytree->x = a;
- mytree->lefttree = mytree->righttree = NULL;
- return mytree;
- }
- bool exnode(Tree x) { //外节点,也就是叶子节点
- if( (x->righttree == NULL) && (x->lefttree == NULL) ) {
- return 1;
- }
- else
- return 0;
- }
- bool innode(Tree x) { //内节点,也就是中间节点
- return !exnode(x);
- }
- //欧拉遍历方式,跟中序遍历类似
- void eulervisit(Tree x) {
- if(exnode(x) ) {
- printf("%c", x->x);
- }
- else {
- printf("(");
- eulervisit(x->lefttree);
- printf("%c", x->x);
- eulervisit(x->righttree);
- printf(")");
- }
- }
- //中序递归的遍历方式
- bool midvisit(Tree x) {
- if(x) {
- if(midvisit(x->lefttree))
- if(printf(" %c ", x->x))
- if(midvisit(x->righttree))
- return 1;
- return 0;
- }
- else
- return 1;
- }
- //前序递归的遍历方式
- bool previsit(Tree x) {
- if(x) {
- if(printf(" %c ", x->x))
- if(previsit(x->lefttree))
- if(previsit(x->righttree))
- return 1;
- return 0;
- }
- else
- return 1;
- }
- //后序递归的遍历方式
- void postvisit(Tree x) {
- if(x) {
- postvisit(x->lefttree);
- postvisit(x->righttree);
- printf(" %c ", x->x);
- }
- }
- //前序的非递归遍历
- void preordervisit(Tree x) {
- LS a;
- initstack(&a);
- Tree p = x;
- while (p || !stackempty(a))
- {
- if (p)
- {
- push(&a, p);
- printf(" %c ", p->x);
- p = p->lefttree;
- }
- else {
- p = pop(&a);
- p = p->righttree;
- }
- }
- }
- //中序的非递归遍历
- void inordervisit(Tree x) {
- LS a;
- initstack(&a);
- Tree p = x;
- while (p || !stackempty(a))
- {
- if (p)
- {
- push(&a, p);
- p = p->lefttree;
- }
- else {
- p = pop(&a);
- printf(" %c ", p->x);
- p = p->righttree;
- }
- }
- }
- /***********************************************************************
- /*后序的非递归遍历,后序遍历有点复杂,
- /*要给出一个标记表明左边和右边子树都已经遍历,
- /*这里就不使用开始时候的堆栈了,
- /*用数组堆栈实现效果更加好,惟一的缺点就是堆栈有最大限制 */
- /************************************************************************/
- void postordervisit(Tree x) {
- Tree stack[100], p;
- int tag[100], top;
- top = 0;
- p = x;
- do
- {
- while (p != NULL) //扫描左子树,入栈
- {
- top++;
- stack[top] = p;
- tag[top] = 0; //右边子树还没有访问设置为0
- p = p->lefttree;
- }
- if (top > 0)
- {
- if (tag[top] == 1)
- {
- printf(" %c ", stack[top]->x);
- top--;
- }
- else {
- p = stack[top];
- if (top > 0)
- {
- p = p->righttree;
- tag[top] = 1;
- }
- }
- }
- } while ((p != NULL) || (top != 0));
- }
- Tree createtree(char *a) { //根据数据结构与算法分析的71页的算法设计一个表达式树
- LS x;
- initstack(&x);
- char *p = a;
- while( *p != '/0') {
- Tree a, b;
- Tree mytree;
- if( isalpha(*p) ) {
- mytree = chartotree(*p);
- push(&x, mytree);
- }
- if( isoperator(*p) ) {
- mytree = chartotree(*p);
- a = pop(&x);
- b = pop(&x);
- mytree->righttree = a;
- mytree->lefttree = b;
- push(&x, mytree);
- }
- p++;
- }
- Tree root = pop(&x);
- return root;
- }
- void deletenode(Tree *p) { //按层遍历
- queue<Tree> que;
- que.push(*p);
- Tree temp;
- while(!que.empty()) {
- temp = que.front();
- que.pop();
- if(temp->lefttree)
- que.push(temp->lefttree);
- if(temp->righttree)
- que.push(temp->righttree);
- //free(temp);
- printf("%c", temp->x);
- temp = NULL;
- }
- }
- int main(int argc, char* argv[])
- {
- LS x;
- initstack(&x);
- if (stackempty(x))
- printf("stack is empty!/n");
- else
- printf("stack is full!/n");
- printf("%c/n", pop(&x));
- char *p = "abc*+b-";
- Tree root = createtree(p);
- //等待进一步的实现来实现二叉树的遍历
- //用到exnode和innode函数
- eulervisit(root);
- puts("/n中序递归");
- midvisit(root);
- puts("/n中序非递归");
- inordervisit(root);
- puts("/n前序递归");
- previsit(root);
- puts("/n前序非递归");
- preordervisit(root);
- puts("/n后序递归");
- postvisit(root);
- puts("/n后序非递归");
- postordervisit(root);
- deletenode(&root);
- return 0;
- }
- 构造一棵表达式二叉树
- 构造一棵表达式树
- 利用中缀表达式构造一棵二叉树(利用了两个栈:符号栈和数字栈)
- 算术表达式构造二叉树; 二叉树计算算术表达式;
- 通过表达式构造二叉树 c++
- 构造一颗表达式树
- 【数据结构】中缀表达式构造二叉树转换成后缀表达式
- 一:构造链式二叉树(—)
- 一:构造链式二叉树(二)
- 二叉树的构造(一)
- 用二叉链表存储结构构造一棵二叉树,然后用栈结构进行非递归遍历
- 先序、中序构造一棵唯一的二叉树
- 给定一个有序的链表或者数组,构造一棵二叉搜索树
- 第十一周项目一(2)~~二叉树构造
- 第十一周项目一 (2)二叉树的构造
- 第十一周 项目一(2)-二叉树的构造
- 第十一周项目一(2)二叉树构造
- 第十一周项目一二叉树构造算法的验证
- 初识Firebug 全文 — firebug的使用
- perl学习笔记(一)
- Asp.net Mvc开发体会点滴 一
- perl学习笔记(二)
- 深度技术GHOST---IE首页修复
- 构造一棵表达式二叉树
- 12种容易创业失败的典型人物
- 最新蜘蛛的Agent和IP地址列表08-09-15
- Fast Start MTTR
- 重新构造datawindow 的 sql select 语句
- Data Mining for Web Intelligence
- 一个很好用的调试辅助类,使用需要一定C++基础
- CStdioFile类打开文件,用TextOut输出时乱码……
- Spring运行中关于bean.xml文件放置的错误解决