二叉树是我们平时使用较多的一种数据结构,它是每个节点最多有两个子树的树结构。关于树的概念和性质就不再多介绍,我来对数的建立和一些操作进行总结。
首先我们定义树的数据类型:
typedef struct TREE_NODE { char data; struct TREE_NODE *lchild; struct TREE_NODE *rchild; }*tree_node;树有一个数据域和两个指针域,采用的是链式存储结构;
我们定义一个tree_node t之后我们首先要创建并输入一个树:
tree_node createTree() //树的建立 { char ch; tree_node t; ch=getchar(); //输入二叉树数据 if(ch=='#') //判断二叉树是否为空 t=NULL; else { t=(tree_node)malloc(sizeof(tree_node)); //二叉树的生成 t->data=ch; t->lchild=createTree(); t->rchild=createTree(); } return t; }在输入树的过程中,我们需要输入符号来判断这个树的节点到这里是否停止了,所以有一个判断if(ch=='#');
这样我们便建立好一个树了,并且输入了数据,我们对数最基本也是重要的操作当然就是遍历,对于树的遍历我们有三种方式,分别是前序遍历,中序遍历,后序遍历,我们先看看递归遍历的方法:
void preOrder(tree_node t) //先序遍历 { if(t) { printf("%c",t->data); preOrder(t->lchild); preOrder(t->rchild); } }
void intOrder(tree_node t) //中序遍历 { if(t) { intOrder(t->lchild); printf("%c",t->data); intOrder(t->rchild); } }
void preOrder(tree_node t) //先序遍历 { if(t) { printf("%c",t->data); preOrder(t->lchild); preOrder(t->rchild); } }这是我们用递归的方式对树进行的遍历,若我们不采用递归的方式,我们如何进行遍历:
void preOrder(tree_node t) //前序遍历 { stack<tree_node> s; tree_node p = t; while(p!=NULL || !s.empty()) { while(p!=NULL) { cout << p->data; s.push(p); p = p->lchild; } if(!s.empty()) { p = s.top(); s.pop(); p = p->rchild; } } }
void intOrder(tree_node t) //中序遍历 { stack<tree_node> s; tree_node p = t; while(p!= NULL || !s.empty()) { while(p!=NULL) { s.push(p); p = p->lchild; } if(!s.empty()) { p = s.top(); cout << p->data; s.pop(); p = p->rchild; } } }
typedef struct node1 { TREE_NODE *btnode; bool isFirst; }*BTNode; void postOrder(tree_node t) //后序遍历 { stack<BTNode> s; tree_node p = t; BTNode q; while(p!=NULL || !s.empty()) { while(p!=NULL) { BTNode bt = (BTNode)malloc(sizeof(BTNode)); bt->btnode = p; bt->isFirst = true; s.push(bt); p = p->lchild; } if(!s.empty()) { q = s.top(); s.pop(); if(q->isFirst ==true) { q->isFirst = false; s.push(q); p = q->btnode->rchild; } else { cout << q->btnode->data; p = NULL; } } } }
非递归的的后序遍历比较麻烦,需要我们沿着左子树一直向下搜索,直到没有左子树的时候,我们此时不能出栈访问,我们还需讲右子树入栈,我们把右子树做了相同处理之后,我们才可以出栈访问,这样我们就需要多设置一个标识每个节点第几次到达栈顶,只有第二次到达栈顶的时候我们才可以出栈访问。
完整的代码如下:
#include<cstdio> #include<cstdlib> #include<iostream> #include<stack> using namespace std; typedef struct TREE_NODE { char data; struct TREE_NODE *lchild; struct TREE_NODE *rchild; }*tree_node; typedef struct node1 { TREE_NODE *btnode; bool isFirst; }*BTNode; tree_node createTree() //树的建立 { char ch; tree_node t; ch=getchar(); //输入二叉树数据 if(ch=='#') //判断二叉树是否为空 t=NULL; else { t=(tree_node)malloc(sizeof(tree_node)); //二叉树的生成 t->data=ch; t->lchild=createTree(); t->rchild=createTree(); } return t; } void preOrder(tree_node t) //先序遍历 { if(t) { printf("%c",t->data); preOrder(t->lchild); preOrder(t->rchild); } } //void preOrder(tree_node t) //先序遍历 //{ // stack<tree_node> s; // tree_node p = t; // while(p!=NULL || !s.empty()) // { // while(p!=NULL) // { // cout << p->data; // s.push(p); // p = p->lchild; // } // if(!s.empty()) // { // p = s.top(); // s.pop(); // p = p->rchild; // } // } //} void intOrder(tree_node t) //中序遍历 { if(t) { intOrder(t->lchild); printf("%c",t->data); intOrder(t->rchild); } } //void intOrder(tree_node t) //中序遍历 //{ // stack<tree_node> s; // tree_node p = t; // while(p!= NULL || !s.empty()) // { // while(p!=NULL) // { // s.push(p); // p = p->lchild; // } // if(!s.empty()) // { // p = s.top(); // cout << p->data; // s.pop(); // p = p->rchild; // } // } //} void postOrder(tree_node t) //后序遍历 { if(t) { postOrder(t->lchild); postOrder(t->rchild); printf("%c",t->data); } } //void postOrder(tree_node t) //后序遍历 //{ // stack<BTNode> s; // tree_node p = t; // BTNode q; // while(p!=NULL || !s.empty()) // { // while(p!=NULL) // { // BTNode bt = (BTNode)malloc(sizeof(BTNode)); // bt->btnode = p; // bt->isFirst = true; // s.push(bt); // p = p->lchild; // } // if(!s.empty()) // { // q = s.top(); // s.pop(); // if(q->isFirst ==true) // { // q->isFirst = false; // s.push(q); // p = q->btnode->rchild; // } // else // { // cout << q->btnode->data; // p = NULL; // } // } // } //} int main() { int num[10]= {0}; int height; int i,a=0; tree_node t; t=createTree(); printf("前序遍历:"); preOrder(t) ; printf("\n"); printf("中序遍历:"); intOrder(t); printf("\n"); printf("后序遍历:"); postOrder(t); printf("\n"); }