课程给出代码
二叉树定义
typedef struct TNode *Position;
typedef Position BinTree; /* 二叉树类型 */
struct TNode{ /* 树结点定义 */
ElementType Data; /* 结点数据 */
BinTree Left; /* 指向左子树 */
BinTree Right; /* 指向右子树 */
};
二叉树四种遍历
void InorderTraversal( BinTree BT )
{
if( BT ) {
InorderTraversal( BT->Left );
/* 此处假设对BT结点的访问就是打印数据 */
printf("%d ", BT->Data); /* 假设数据为整型 */
InorderTraversal( BT->Right );
}
}
void PreorderTraversal( BinTree BT )
{
if( BT ) {
printf("%d ", BT->Data );
PreorderTraversal( BT->Left );
PreorderTraversal( BT->Right );
}
}
void PostorderTraversal( BinTree BT )
{
if( BT ) {
PostorderTraversal( BT->Left );
PostorderTraversal( BT->Right );
printf("%d ", BT->Data);
}
}
void LevelorderTraversal ( BinTree BT )
{
Queue Q;
BinTree T;
if ( !BT ) return; /* 若是空树则直接返回 */
Q = CreatQueue(); /* 创建空队列Q */
AddQ( Q, BT );
while ( !IsEmpty(Q) ) {
T = DeleteQ( Q );
printf("%d ", T->Data); /* 访问取出队列的结点 */
if ( T->Left ) AddQ( Q, T->Left );
if ( T->Right ) AddQ( Q, T->Right );
}
}
03-树1 树的同构 (25 分)
题目:给定两棵树T1和T2。如果T1可以通过若干次左右孩子互换就变成T2,则我们称两棵树是“同构”的。例如图1给出的两棵树就是同构的,因为我们把其中一棵树的结点A、B、G的左右孩子互换后,就得到另外一棵树。而图2就不是同构的。
#include <iostream>
using namespace std;
#define MaxTree 10
#define Null -1
struct TreeNode
{
char data;
int left;
int right;
}T1[MaxTree],T2[MaxTree];
int BuildTree(struct TreeNode T[])
{
int N,i;
int check[MaxTree] = { 0 };
char CL, CR;
cin >> N;
int root=-1;
if (N)
{
for (i = 0; i < N; i++)
{
cin >> T[i].data >> CL >> CR;
if (CL != '-')
{
T[i].left = CL - '0';
check[T[i].left] = 1;
}
else
T[i].left = Null;
if (CR != '-')
{
T[i].right = CR - '0';
check[T[i].right] = 1;
}
else
T[i].right = Null;
}
for(i = 0;i < N; i++ )
if(!check[i])
break;
root= i;
}
return root;
}
int Isomorphic(int R1, int R2)
{
if (R1==Null&&R2==Null) //均空
return 1;
if ((R1==Null&&R2!=Null)||(R1!=Null&&R2==Null))//有一个空
return 0;
if (T1[R1].data!=T2[R2].data)//根节点不同
return 0;
if (T1[R1].left==Null&&T2[R2].left==Null)//左节点均空,递归右节点
return Isomorphic(T1[R1].right, T2[R2].right);
if (((T1[R1].left!=Null)&&(T2[R2].left!=Null))&&(T1[T1[R1].left].data==T2[T2[R2].left].data))//左节点有值且相同,递归左节点与右节点。
return (Isomorphic(T1[R1].left, T2[R2].left)&& Isomorphic(T1[R1].right, T2[R2].right));
else //再同构只能是发生左右节点互换了
return (Isomorphic(T1[R1].left, T2[R2].right)&& Isomorphic(T1[R1].right, T2[R2].left));
}
int main()
{
int root1 = BuildTree(T1);
int root2 = BuildTree(T2);
if (Isomorphic(root1, root2))
cout << "Yes" << endl;
else
cout << "No" << endl;
return 0;
}
ps:仿本节PPT写的,已通过测试。
03-树2 List Leaves (25 分)
题目:Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.
按层扫描,并输出叶子节点。
#include <iostream>
using namespace std;
#define MaxTree 10
#define Null -1
struct TreeNode
{
int data;
int left;
int right;
}T[MaxTree];
int BuildTree(struct TreeNode T[])
{
int N,i;
int check[MaxTree] = { 0 };
char CL, CR;
cin >> N;
int root=-1;
if (N)
{
for (i = 0; i < N; i++)
{
T[i].data =i;
cin >> CL >> CR;
if (CL != '-')
{
T[i].left = CL - '0';
check[T[i].left] = 1;
}
else
T[i].left = Null;
if (CR != '-')
{
T[i].right = CR - '0';
check[T[i].right] = 1;
}
else
T[i].right = Null;
}
for(i = 0;i < N; i++ )
if(!check[i])
break;
root= i;
}
return root;
}
int main()
{
int root = BuildTree(T);
int Queue[10]={0};
int rear=-1,front=-1,M=0;
struct TreeNode p;
Queue[++rear]=root;
while(front!=rear){ //队列不为空
p=T[Queue[++front]]; //队头取出节点
if(p.left!=-1)
Queue[++rear]=p.left; //左节点非空队尾插入左节点
if(p.right!=-1)
Queue[++rear]=p.right; //右节点非空队尾插入右节点
if(p.left==-1&&p.right==-1){ //左右均空则为叶子节点,输出
if(M)
cout << " " ;
M++;
cout << p.data;
}
}
return 0;
}
03-树3 Tree Traversals Again (25 分)
题目:An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.
堆栈的操作其实是中序遍历的结果,而在此过程中每次push的顺序又是前序遍历的结果(123456),因此此题就是已知前序中序遍历求后序遍历的过程。
#include<iostream>
using namespace std;
#define MAXSIZE 30
//建立一个堆栈
int stack[MAXSIZE];
int top = 0;
//建立三个数组存放三种遍历
int PreorderTraversal[MAXSIZE];
int InorderTraversal[MAXSIZE];
int PostorderTraversal[MAXSIZE];
//建立三个整数型对应遍历的位次
int pre_p = 0;
int in_p = 0;
int post_p = MAXSIZE-1;
void push(int x){
stack[top++] = x;
}
int pop(){
return stack[--top];
}
void TranPost(int pre_list[], int in_list[], int len){
int rootIndex = 0;
if(len == 0)
return;
PostorderTraversal[post_p--] = pre_list[0]; //将当前根节点放置后序队列最后
for(;rootIndex < len;rootIndex++){ //寻找子树,下一个根节点
if(in_list[rootIndex] == pre_list[0])
break;
}
TranPost(pre_list+rootIndex+1,in_list+rootIndex+1,len-rootIndex-1);//后续遍历先递归右子树
TranPost(pre_list+1,in_list,rootIndex); //遍历左子树
}
int main(){
int Node_num,num;
string s;
cin >> Node_num;
int all = 2*Node_num;
while(all--){
cin >> s;
if(!s.compare("Push")){
cin >> num;
push(num);
PreorderTraversal[pre_p++] = num;
}else{
InorderTraversal[in_p++] = pop();
}
}//获取到前序和中序数组
TranPost(PreorderTraversal,InorderTraversal,Node_num);
for(int i = MAXSIZE-Node_num; i < MAXSIZE-1; i++)
cout << PostorderTraversal[i] << " ";
cout << PostorderTraversal[MAXSIZE-1] << endl;
return 0;
}