pta数据结构day8

总结:昨天没写题,今天开始树的学习,刷了三道关于树的遍历的题目;树的遍历分为先序,后序,中序和层序遍历,前三种可以使用递归或非递归实现,后者使用队列实现;然后在遍历时,也可以顺带做到求树的叶子节点,高度,转换二元运算表达式等。

第一题是 三种二叉树的非递归遍历,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);
}

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值