总结:昨天没写题,今天开始树的学习,刷了三道关于树的遍历的题目;树的遍历分为先序,后序,中序和层序遍历,前三种可以使用递归或非递归实现,后者使用队列实现;然后在遍历时,也可以顺带做到求树的叶子节点,高度,转换二元运算表达式等。
第一题是 三种二叉树的非递归遍历,mooc视频中有中序的,按照思路把另外两种补充好即可。
void InorderTraversal( BinTree BT ){
BinTree t=BT;
Stack stack=CreateStack();
while(t||!IsEmpty(stack)){
while(t){
Push(stack,t);
t=t->Left;
}
t=Pop(stack);
printf(" %c",t->Data);
t=t->Right;
}
}
void PreorderTraversal( BinTree BT ){
BinTree t=BT;
Stack stack=CreateStack();
while(t||!IsEmpty(stack)){
while(t){
printf(" %c",t->Data);
Push(stack,t);
t=t->Left;
}
t=Pop(stack);
t=t->Right;
}
}
void PostorderTraversal( BinTree BT ){
Stack stack=CreateStack();
BinTree t=BT;
while(t||!IsEmpty(stack)){
while(t){
Push(stack,t);
t->flag=1;
t=t->Left;
}
t=Peek(stack);
if(t->flag==1){
t->flag++;
t=t->Right;
}else{
printf(" %c",t->Data);
Pop(stack);
t=NULL;
}
}
}
第二题是列出叶结点,我感觉树的遍历有个通用思路(不一定省时间),先想一种储存结构建立树,然后遍历,最后添加一定的条件。这题中,我先用结构数组(静态链表)储存,然后用队列遍历,最后添加没有左右子树时可以输出的条件;
#include<iostream>
#include<string>
#include<queue>
using namespace std;
struct node {
int data;
int left, right;
};
int main() {
int n;
char c1,c2;
cin >> n;
node p[10];
queue<int>q;
int root=-1;
int arr[10] = { 0 };
for (int i = 0; i < n; i++) {
p[i].data = i;
cin >> c1 >> c2;
if (c1 == '-') {
p[i].left = -1;
}
else {
p[i].left = 0+ c1 - '0';
arr[p[i].left] = 1;
}
if (c2 == '-') {
p[i].right = -1;
}
else {
p[i].right = 0 + c2 - '0';
arr[p[i].right] = 1;
}
}
for (int i = 0; i < n; i++) {
if (!arr[i]) {
root = i;
}
}
q.push(root);
int flag=1;
while (!q.empty()) {
if (p[q.front()].left == -1&& p[q.front()].right == -1) {
if(flag){
cout << q.front();
--flag;
}else{
cout <<' ' <<q.front();
}
}
if (p[q.front()].left != -1) {
q.push(p[q.front()].left);
}
if (p[q.front()].right != -1) {
q.push(p[q.front()].right);
}
q.pop();
}
return 0;
}
第三题是根据后序和中序遍历输出先序遍历,这里我不选择建立树,而是直接用数组储存先序的结果,然后直接输出即可。
#include<iostream>
#include<string>
#include<vector>
using namespace std;
class solution {
public:
solution() {
cin >> n;
index = 0;
input(post);
input(in);
}
private:
int n,in[30], post[30], pre[30],index;
void input(int p[]) {
for (int i = 0; i < n; i++) {
cin >> p[i];
}
}
public:
void transfer(int in[],int post[],int n);
void show() {
this->transfer(in, post, n);
cout << "Preorder:";
for (int i = 0; i < index; i++) {
cout << ' ' << pre[i];
}
}
};
int main() {
solution p;
p.show();
return 0;
}
void solution::transfer(int in[], int post[], int n) {
int p;
if (n == 0) {
return;
}
pre[index++] = post[n - 1];
for (p = 0; p < n; p++) {
if (in[p] == post[n - 1]) {
break;//跳到下一句,不会p++
}
}
transfer(in,post,p);//递归左右子树
transfer(in+p+1,post+p,n - p - 1);
}