一、编写一个程序,实现由先序遍历序列和中序遍历序列构造一棵二叉树
先序序列:A B D M R N S C E P G Q F H T J
中序序列:R M D N S B A P E Q G C H T F J
要求:
1. 用凹入表示法输出该二叉树。其中二叉树用二叉链表结构存储。
2. 用递归算法实现对此二叉树各结点的后序遍历。
3. 用非递归算法实现对此二叉树各结点的后序遍历。
注意:根据这两个序列构造二叉树来验证程序,后面的题目用到的二叉树均用这个二叉树来验证。
注释:凹入表示法输出, 比如给定一棵二叉树
a
/ /
b c
/ / / /
d e f g
凹入表示法输出结果为:
a
b
d
e
c
f
g
二、设计将二叉链表存储的二叉树转换为一维数组结构的算法,并输出这个数组,空值则用‘*’代替。并以第一题中实验数据来验证。
例如给定一棵二叉树
a
/ /
b c
/ /
d f
输出: a b c d * * f
三、以第一题的实验数据来验证完成下列问题:
1. 求一二叉链表存储的二叉树的结点个数,并输出。
2. 求一二叉链表存储的二叉树的叶结点个数,并输出。
四、编写一个程序,实现对一棵给定二叉链表结构存储的二叉树中序线索化,并完成该线索化二叉树遍历的算法。以第一题的实验数据来验证。
#include <iostream>
#include <string>
using namespace std;
//******************************
//结点
struct Binary_node
{
Binary_node();
char data;
Binary_node *left;
Binary_node *right;
int f_left;
int f_right;
};
Binary_node::Binary_node()
{
f_left=0;
f_right=0;
left=NULL;
right=NULL;
}
//***************************************
//这个栈用来存放Binary_node型数据
const int maxstack = 30;
class Stack
{
public:
Stack();
bool empty() const;
Binary_node pop();
Binary_node gettop();
void push(const Binary_node &item);
private:
friend class Binary_tree;
int count;
Binary_node entry[maxstack];
};
void Stack::push(const Binary_node &item)
{
if(count>=maxstack)
cout<<"overflow "<<endl;
else
entry[count++]=item;
}
Binary_node Stack::pop()
{
Binary_node item;
if(count==0)
{
return item;
}
else
{
item=entry[count-1];
--count;
return item;
}
}
Binary_node Stack::gettop()
{
Binary_node item;
if(count==0)
{
item.data='/0';
}
else
{
item=entry[count-1];
}
return item;
}
bool Stack::empty() const
{
bool outcome=true;
if(count>0)
outcome=false;
return outcome;
}
Stack::Stack()
{
count=0;
}
//*********************************************
//这个栈用来存放int型数据
const int maxstack1 = 100;
class IntStack
{
public:
IntStack();
bool empty() const;
int pop();
int gettop();
void push(const int &item);
private:
friend class Binary_tree;
int count;
int entry[maxstack1];
};
void IntStack::push(const int &item)
{
if(count>=maxstack)
cout<<"overflow "<<endl;
else
entry[count++]=item;
}
int IntStack::pop()
{
int item;
if(count==0)
{
item=-1;
return item;
}
else
{
item=entry[count-1];
--count;
return item;
}
}
int IntStack::gettop()
{
int item;
if(count==0)
{
item=-1;
}
else
{
item=entry[count-1];
}
return item;
}
bool IntStack::empty() const
{
bool outcome=true;
if(count>0)
outcome=false;
return outcome;
}
IntStack::IntStack()
{
count=0;
}
//***********************************************
//队列
#define max_queue 50
class Queue
{
public:
Queue():current(0),first(0){}
bool empty() const;
bool full() const;
Binary_node* append(Binary_node *sub_root);
Binary_node* serve();
protected:
Binary_node* workspace[max_queue];
int current, first;
};
bool Queue::empty() const
{
bool outcome = true;
if (current>0)
outcome = false;
else
cout<<"empty queue"<<endl;
return outcome;
}
bool Queue::full()const
{
return current==max_queue;
}
Binary_node* Queue::append(Binary_node *sub_root)//入队
{
if (full())
{
return NULL;
}
workspace[current]=sub_root;
current++;
return sub_root;
}
Binary_node* Queue::serve() //出队
{
if (empty())
{
return NULL;
}
Binary_node *sub_root;
sub_root = workspace[first];
first++;
return sub_root;
}
//***********************************************
//二叉树
class Binary_tree
{
public:
Binary_tree(){}
Binary_node* createtree(char *pre,char *in); //用先序遍历序列和中序创遍历序列建二叉树
int countsize(Binary_node *sub_root); //输出所有结点个数
int leaf_countsize(Binary_node *sub_root); //输出叶子节点个数
void postorder(Binary_node *sub_root) const; //后序递归遍历
void levelorder(Binary_node *sub_root, int sheight) const; //层次遍历,将二叉树转换为一维数组结构
void showtree(Binary_node* sub_root,int depth); //凹入表示法输出
int height(Binary_node* sub_root) const; //树的深度
void postorder_norecursion(Binary_node *sub_root); //后序非递归遍历
protected:
Binary_node *createNode(char &c); //建立新结点
int searchchar(char &c,char *order); //找先序第一个元素在中序中的位置
};
Binary_node* Binary_tree::createNode(char &ch) //初始化结点
{
Binary_node *n=new Binary_node;
n->data=ch;
n->left=NULL;
n->right=NULL;
return n;
}
int Binary_tree::searchchar(char &ch,char *order) //找先序第一个元素在中序中的位置
{
for(unsigned int i=0;i<strlen(order);i++)
{
if(ch==order[i])
return i;
}
return -1;
}
Binary_node* Binary_tree::createtree(char *pre,char *in) //用先序遍历序列和中序创遍历序列建二叉树
{
char ch=pre[0];
char temppre[100];
char tempin[100];
char *p;
int i=0;
Binary_node* bnode;
if(pre=='/0')
return NULL;
for (int ix=0;ix!=100;ix++) //初始化tempin
{
tempin[ix]='/0';
}
for (int ix=0;ix!=100;ix++) //初始化temppre
{
temppre[ix]='/0';
}
bnode=createNode(ch); //初始化结点
i=searchchar(pre[0],in); //找先序第一个元素在中序中的位置,划分左右子树
if(i==-1)
return 0;
p=in;
strncpy_s(tempin,p,i); //将in的前i个元素赋给tempin
p=pre;
strncpy_s(temppre,p+1,i);
bnode->left=createtree(temppre,tempin); //左子树
for (int ix=0;ix!=100;ix++)
{
tempin[ix]='/0';
}
for (int ix=0;ix!=100;ix++)
{
temppre[ix]='/0';
}
p=in+i+1;
strncpy_s(tempin,p,strlen(in)-i);
p=pre+i+1;
strncpy_s(temppre,p,strlen(in)-i);
bnode->right=createtree(temppre,tempin); //右子树
return bnode;
}
void Binary_tree::showtree(Binary_node* sub_root,int depth) //凹入表示法输出
{
if(sub_root!=NULL)
{
for (int i=0; i<depth+1; i++)
{
cout<<" "; //输出空格
}
cout<<sub_root->data<<endl;
showtree(sub_root->left, depth+1);
showtree(sub_root->right, depth+1);
}
}
void Binary_tree::postorder(Binary_node *sub_root) const //后续递归遍历
{
if ( sub_root!=NULL){
postorder(sub_root->left); // 遍历左子树
postorder(sub_root->right); // 遍历右子树
cout<<sub_root->data<<" ";
}
}
void Binary_tree::postorder_norecursion(Binary_node *sub_root) //后序非递归遍历
//标志栈中 0表示结点暂时不访问
//1表示结点可以访问
{
Stack stackForNode; //存储结点
IntStack stackForTag; //存储标志
stackForNode.push(*sub_root);
stackForTag.push(0);
Binary_node *tempNode= sub_root->left;
while (tempNode!=NULL|| stackForNode.empty()!= true)
{
while (tempNode!=NULL)
{
stackForNode.push(*tempNode);
stackForTag.push(0);
tempNode= tempNode->left;
}
while (stackForNode.empty()!= true && stackForTag.gettop() == 1)
{
stackForTag.pop();
cout<<stackForNode.pop().data<<" ";
}
if (stackForNode.empty() != true)
{
stackForTag.pop();
stackForTag.push(1);
tempNode = stackForNode.gettop().right;
}
}
}
//第二题
void Binary_tree::levelorder(Binary_node *sub_root, int sheight) const //层次遍历,将二叉树转换为一维数组结构
{
Queue que;
Binary_node *p;
que.append(sub_root);
for(int i=-1; i!=sheight+1;++i) // 继续进行以下处理,直到队列为空
{
p = que.serve(); // 出队列
if (p->data!='0')
{
cout<<p->data<<" "; // 访问结点
}
else
cout<<"* ";
if (p->left !=NULL)
que.append( p->left); //左孩子入队
else
{
Binary_node *n1 = new Binary_node;
n1->data = '0';
que.append(n1);
}
if (p->right!=NULL)
{
que.append(p->right); //右孩子入队
}
else
{
Binary_node *n2 = new Binary_node;
n2->data = '0';
que.append(n2);
}
}
}
int Binary_tree::height(Binary_node* sub_root) const
{
int lheight = 0,rheight = 0,sheight = 0;
if (sub_root == NULL)
sheight = 0;
else
{
lheight = height(sub_root->left); // 计算左子树深度
rheight = height(sub_root->right); // 计算右子树深度
sheight = 1+(lheight>rheight ? lheight:rheight); //取较大者
}
return sheight;
}
int Binary_tree::countsize(Binary_node* sub_root) //计算结点数 第三题(a)
{
int ileft = 0,iright = 0,count = 0;
if(sub_root == NULL)
count = 0;
else
{
ileft = countsize(sub_root->left);
iright = countsize(sub_root->right);
count = ileft + iright + 1;
}
return count;
}
int Binary_tree::leaf_countsize(Binary_node* sub_root) //计算叶子节点数 第三题(b)
{
int count;
if(sub_root==NULL)
{
count=0;
}
else if((sub_root->left==NULL)&&(sub_root->right==NULL)) //叶子节点
{
count=1;
}
else
count=leaf_countsize(sub_root->left)+leaf_countsize(sub_root->right);
return count;
}
//*********************************************Thread_tree 类 第四题
class Thread_tree
{
public:
Thread_tree():pre(NULL){}
Binary_node* inthrRealize(); //线索化二叉树
void thread_inorder(Binary_node* current); //中序线索化
void in_thr_travel(Binary_node* head) ; //线索化二叉树的中序遍历
Binary_node *root;
protected:
Binary_node *pre;
};
Binary_node* Thread_tree::inthrRealize() //线索化二叉树
{
Binary_node* head = new Binary_node;
head->f_left = head->f_right = 1;
if(root == NULL)
{
head->left = head;
head->right = head;
}
else
{
head->left = root;
head->f_left = 0;
thread_inorder(root);
pre->right = head;
pre->f_right = 1;
head->right = pre;
}
return head;
}
void Thread_tree::thread_inorder(Binary_node* current)
{
if(current != NULL)
{
thread_inorder(current->left); // 左子树线索化
if(current->left == NULL)
{
current->left = pre;
current->f_left = 1;
}
if(pre != NULL)
if (pre->right == NULL)
{
pre->right = current;
pre->f_right = 1;
}
pre = current;
thread_inorder(current->right); // 右子树线索化
}
}
void Thread_tree::in_thr_travel(Binary_node* head) //线索化二叉树的中序遍历
{
Binary_node* current;
current = head->left;
while(current != head)
{
while(current->f_left == 0)
current=current->left;
cout<<current->data;
while(current->f_right == 1 && current->right != head)
{
current = current->right;
cout << current->data;
}
current = current->right;
}
}
int main()
{
Binary_tree tree;
Binary_node* root;
char pre_order[100];
char in_order[100];
cout<<"第一题"<<endl;
cout<<"请输入前序序列:";
cin>>pre_order;
cout<<"请输入中序序列: ";
cin>>in_order;
root = tree.createtree(pre_order,in_order);
cout<<endl;
tree.showtree(root,-1);
cout<<endl;
cout<<"递归方法后序遍历的结果为: ";
tree.postorder(root);
cout<<endl;
cout<<"非递归方法后序遍历的结果为: ";
tree.postorder_norecursion(root);
cout<<endl;
cout<<endl;
cout<<"第二题"<<endl;
int isize;
isize=tree.height(root);
tree.levelorder(root,isize);
cout<<endl;
cout<<endl;
cout<<"第三题"<<endl;
int number,leaf_number;
number=tree.countsize(root);
leaf_number=tree.leaf_countsize(root);
cout<<"BiTree中结点个数为 "<<number<<", 叶节点个数为 "<<leaf_number<<endl;
cout<<endl;
cout<<"第四题"<<endl;
Thread_tree *Ttree = new Thread_tree;
Ttree->root=root;
Binary_node* head = Ttree->inthrRealize();
cout << "二叉树中序线索化遍历结果:";
Ttree->in_thr_travel(head);
cout<<endl;
delete Ttree;
return 0;
}