二叉树遍历算法的应用
1)二叉树的叶子节点个数
////二叉树叶子节点,使用先序遍历方法,叶子节点的特点为左右孩子节点为空
find_leaf(Btree* t,int& n) { if(t) { if(!t->lchild&&!t->rchild) { ++n; } find_leaf(t->lchild,n); find_leaf(t->rchild,n); } }
2)二叉树深度
//二叉树的深度,主要考虑左右子树的深度最大者加1为树的深度,因为要算出左右子树的深度,所以使用后序遍历 int tree_deep(Btree* t) { if(!t) { return 0; } else { int l_deep=tree_deep(t->lchild); int r_deep=tree_deep(t-rchild); return l_deep>=r_deep?(l_deep+1):(r_deep+1); } }
3)二叉树的复制
//复制二叉树,首先是对一个节点的复制,主要是生成空间,复制数据信息,然后复制左子树,然后复制右子树,所以用后续遍历,首先查找做子树,然后右子树 BtreeNode* tree_copy(Btree* t) { if(!t) return NULL; if(t->lchild) BtreeNode* ltree=tree_copy(t->child); else ltree=NULL; if(t->rchild) BtreeNode* rtree=tree_copy(r->child); else rtree=NULL; BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeBode)); if(!p) return NULL; p->elem=t->elem; p->lchild=ltree; p->rchild=rtree; return p; }
4)二叉树链表的构造
//1. 根据已知字符的先序序列构造二叉树,为空的子树用空格表示 void creat_tree(Btree* t) { char ch=getchar(); if(ch==\' \') return t=NULL; t=(BtreeNode*)molloc(sizeof(BtreeNode)); if(!t) exit(overflow_error); t->elem=ch; creat_tree(t->lchild); creat_tree(t->rchild); }
//2. 根据表达式建立二叉树
//已知表达式的先序序列,然后建立二叉树 //二元表达式性质我们可知,如果字符为运算符则必定存在左右子树 //如果为字符则左右子树必定为空,根据这两个性质使用先序遍历建立二叉树
//(a+b)*c-d/e
//先序表达式-*+abc/de
void creat_tree(Btree* t) { char ch; ch=getchar(); t=(BtreeNode*)molloc(sizeof(BtreeNode)); if(!t) exit(overflow_error); t->elem=ch; if(ch==\'运算符\') { creat_tree(t->lchild); creat_tree(t->rchild); } else { t->lchild=NULL; t->rchild=NULL;
return; } }
//已知后缀表达式,建立二叉树 void creat_tree(BtreeNode* t) { stack<BtreeNode*> s; char ch; while(ch=getchar()) { if(ch==\'运算符\') { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->rchild=s.pop(); p->lchild=s.pop(); t=p; s.push(p); } else { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error) p->elem=ch; p->rchild=NULL; p->lchild=NULL; } } }
//根据表达式建立二叉树或者后缀式建立二叉树,使用表达式的后缀表示方法建立二叉树,表达式的后缀表示法使用栈来建立 //所以需要使用两个栈,一个栈存储表达式的运算符,一个栈用于存储子树的根节点指针 void creat_tree(Btree* t) { stack* sexp; stack* stree; sexp.push("#"); char ch; while(ch=getchar()) { switch(ch) { case \'(\': { sexp.push(ch); break; } case \')\': { char c; while((c=sexp.pop())!=\'(\') { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->rchild=stree.pop(); p->lchild=stree.pop(); stree.push(p); } break; } case \'运算符\': { if(comp(ch,sexp.top()))//比较运算符的优先级,优先级大入栈 sexp.push(ch); else { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->rchild=stree.pop(); p->lchild=stree.pop(); stree.push(p); } break; } case \'#\': { char c; while((c=sexp.pop())!=\'#\') { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->rchild=stree.pop(); p->lchild=stree.pop(); stree.push(p); } } default: { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->rchild=NULL; p->lchild=NULL; stree.push(p); } } } }
//已知前缀表达式的非递归算法 void creat_tree(Btree* t) { char ch; stack<BtreeNode*> s; while(ch=getchar()) { if(ch=\'运算符\') { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; if(!s.empty()) { BtreeNode *q=s.top(); if(!q->lchild) { q->lchild=p; s.push(q); } else { q->rchild=p; s.pop(); s.push(p); } } } else { BtreeNode* p=(BtreeNode*)malloc(sizeof(BtreeNode)); if(!p) exit(overflow_error); p->elem=ch; p->lchild=NULL; p->rchild=NULL; BtreeNode *q=s.top(); if(!q->lchild) { q->lchild=p; } else { q->rchild=p; s.pop(); } } } }
//3.根据先序和中序,或者中序和后序建立二叉树链表