结构体定义:
struct node{
int data; //数据内容
node* lchild; //左孩子指针
node* rchild; //右孩子指针
};
二叉树的创建:
//通过后序序列和中序序列创建二叉树
//当前二叉树的后序序列区间为[postL, postR],中序序列为[inL, inR]
node* create(int postL,int postR,int inL,int inR){
if(postL > postR) return NULL; //若后序序列长度小于0,直接返回
node* root = new node; //创建一个新结点,用来存放当前二叉树的根结点
root->data = postOrder[postR]; //新结点的数据域为根结点的值,也就是当前后序序列的最后一个
int k;
for(k=inL; k<=inR; k++){ //找到中序序列中第一个与根结点值相同的位置k
if(inOrder[k] == postOrder[postR]) break;
}
int numLeft = k-inL; //从k往左一直到当前中序序列的最左边
//当前创建的结点root左孩子部分的中序序列为[inL,k-1],后序序列为[postL, postL+numLeft-1]
root->lchild = create(postL, postL+numLeft-1, inL, k-1);
//当前创建的结点root右孩子部分的中序序列为[k+1,inR],后序序列为[postL+numLeft,postR-1]
root->rchild = create(postL+numLeft, postR-1, k+1, inR);
return root;
}
//通过先序序列和中序序列创建二叉树
//当前二叉树的先序序列区间为[preL, preR],中序序列为[inL, inR]
Node* creat(int inL, int inR, int preL, int preR){
if(preL > preR) return NULL;
Node* root = new Node;
root->data = preArr[preL];
int k;
for(k=inL; k<=inR; k++){
if(inArr[k] == preArr[preL]) break;
}
int numLeft = k-inL;
root->left = creat(inL,k-1,preL+1, preL+numLeft);
root->right = creat(k+1, inR, preL+numLeft+1, preR);
return root;
}
二叉树的遍历
//层序遍历
queue<Node*> qu;
void layerTraversal(Node* root){
while(!qu.empty()) qu.pop();
qu.push(root);
while(!qu.empty()){
Node* node = qu.front();
qu.pop();
printf("%d ",node->data);
if(node->left) qu.push(node->left);
if(node->right) qu.push(node->right);
}
}
//先序遍历、中序遍历和后序遍历——递归方式
void postTraversal(Node* root){
if(!root) return;
postTraversal(root->left);
postTraversal(root->right);
printf("%d",root->data); //输出语句的位置相对应为遍历顺序
}
//先序序列的遍历——非递归方式
void preTraversal(Node* root){
stack<Node* > stack;
while(!stack.empty()) stack.pop();
Node* p = root;
while(p || !stack.empty()){
if(p){
printf("%d ",p->data);
stack.push(p); //访问结点后入栈
p = p->left; //往左子树继续访问
}else{
p = stack.top(); //没有左子树了,取栈顶元素
p = p->right; //往栈顶元素的右子树继续访问
stack.pop(); //将栈顶元素出栈
}
}
}
//中序序列的遍历——非递归方式
void inTraversal(Node* root){
stack<Node* > stack;
while(!stack.empty()) stack.pop();
Node* p = root;
while(p || !stack.empty()){
if(p){
stack.push(p); //将结点入栈
p = p->left; //往当前结点的左子树继续遍历
}else{
p = stack.top(); //取栈顶结点
stack.pop(); //弹出栈顶结点
printf("%d ",p->data); //输出结点
p = p->right; //往结点右子树继续遍历
}
}
}
//后序遍历的非递归方式
void postTraversal(Node* root){
stack<Node* > stack;
while(!stack.empty()) stack.pop();
Node* p = root;
Node* r = NULL;
while(p || !stack.empty()){
if(p){
stack.push(p); //将结点入栈
p = p->left; //继续访问结点的左子树
}else{
p = stack.top(); //没有左子树了,取栈顶结点
if(p->right && p->right != r){ //如果结点有右子树并且未被访问过
p = p->right; //继续访问结点的右结点
stack.push(p); //将右结点入栈
p = p->left; //继续访问结点的左子树
}else{//要么就是没有右子树(表示这个结点是叶节点),要么就是右子树已经被访问过
stack.pop(); //弹出栈顶元素
printf("%d ",p->data); //输出元素
r = p; //标记当前节点已经被访问过
p = NULL; //将访问指针置空
}
}
}
}