树的遍历
1.设计思路:
①先利用利用递归,将中序和后序遍历序列构造成二叉树。
②采用层次遍历输出该树序列。
2.实现:
#include <iostream>
#include <stdio.h>
#include <malloc.h>
using namespace std;
#define MaxSize 30
typedef int ElemType;
typedef struct node
{
ElemType data;
struct node *lchild;
struct node *rchild;
}BTNode;
void DestroyBTree(BTNode *b)
{
if(b!=NULL)
{
DestroyBTree(b->lchild);
DestroyBTree(b->rchild);
free(b);
}
}
BTNode *CreateBT2(int *post,int *in,int n)
{
BTNode *b;
int r,*p;
int k;
if(n<=0) return NULL;
r=*(post+n-1);
b=(BTNode *)malloc(sizeof(BTNode));
b->data=r;
for(p=in;p<in+n;p++)
if(*p==r)break;
k=p-in;
b->lchild=CreateBT2(post,in,k);
b->rchild=CreateBT2(post+k,p+1,n-k-1);
return b;
}
void TravLevel(BTNode *b)
{
BTNode *Qu[MaxSize];
int fron,rear;
fron=rear=0;
if(b!=NULL) printf("%d",b->data);
rear++;
Qu[rear]=b;
while(rear!=fron)
{
fron=(fron+1)%MaxSize;
b=Qu[fron];
if(b->lchild!=NULL)
{
printf(" %d",b->lchild->data);
rear=(rear+1)%MaxSize;
Qu[rear]=b->lchild;
}
if(b->rchild!=NULL)
{
printf(" %d",b->rchild->data);
rear=(rear+1)%MaxSize;
Qu[rear]=b->rchild;
}
}
}
int main()
{
int n;
BTNode *b;
ElemType in[MaxSize],post[MaxSize];
cin>>n;
for(int i=0;i<n;i++)
cin>>post[i];
for(int i=0;i<n;i++)
cin>>in[i];
b=CreateBT2(post,in,n);
TravLevel(b);
DestroyBTree(b);
return 0;
}
3.运行结果:
列出叶结点
1.设计思路:
①按照题目中的输入,根节点是肯定不会出现在这里面的,所以我们只需要找到没有出现的数字,然后就可以确定根节点,有了根节点,然后再模拟队列的性质,依次把他的左孩子,右孩子插入进来,然后遍历指针+1,继续插入根节点的左孩子的左孩子和右孩子。
②用到一个辅助数组checked用来确定哪一个数字没有出现过,那就是根节点。
③有了根节点,下一步需要一个队列ans,首先把根节点存进去,然后从根节点开始,左孩子,右孩子,左孩子的(左孩子,右孩子),右孩子的(左孩子,右孩子)…,最后,遍历ans数组,如果有一个的 left 和 right 都是-1,那么说明这个就是叶结点。
2.实现:
#include <iostream>
#include <stdio.h>
using namespace std;
struct Node
{
int data;
int left;
int right;
};
int main()
{
int n;
cin >> n;
getchar();
Node tree[15];
int checked[15] = {};
for(int i = 0;i < n;i++)
{
char l,r;
scanf("%c %c",&l,&r);
getchar();
if(l == '-')tree[i].left = -1;
else
{
tree[i].left = (l - '0');
checked[l - '0'] = 1;
}
if(r == '-')tree[i].right = -1;
else
{
tree[i].right = (r - '0');
checked[r - '0'] = 1;
}
}
int ans[15] = {};
for(int i = 0;i < n;i++)
{
if(checked[i] == 0)
{
ans[0] = i;
break;
}
}
int k = 1;
for(int i = 0;i < n;i++)
{
if(tree[ans[i]].left != -1)ans[k++] = tree[ans[i]].left;
if(tree[ans[i]].right != -1)ans[k++] = tree[ans[i]].right;
}
int flag = 0;
for(int i = 0;i < n;i++)
{
if(tree[ans[i]].left == -1 && tree[ans[i]].right == -1)
{
if(flag)cout << " ";
flag = 1;
cout << ans[i];
}
}
return 0;
}
3.运行结果:
二叉树的遍历
1.设计思路:
①首先先理解题目的意思。题目给出N行数组,每一行表示的是第N个节点的左右孩子的编码,若无左右孩子则标为0,即为叶节点。
②先定义一个数组将左右孩子编码输入,然后调用递归。由于题目已经规定根节点是1,因此先输出根节点,若当前访问节点的左右孩子不为0,则依次访问其左右孩子,输出先序序列。
2.实现:
#include <iostream>
using namespace std;
struct Node
{
int lChild;
int rChild;
};
void Pre_traverse(Node nodes[], int root);
int main()
{
int N;
cin >> N;
Node nodes[N + 1];
for (int i = 1; i <= N; i++)
{
cin >> nodes[i].lChild >> nodes[i].rChild;
}
Pre_traverse(nodes, 1);
}
void Pre_traverse(Node nodes[], int root)
{
if (root == 0)
return;
cout << root << " ";
Pre_traverse(nodes, nodes[root].lChild);
Pre_traverse(nodes, nodes[root].rChild);
}