例题6-10 The Falling Leaves,UVA699

这道题我的思路是先通过递归构建树,然后进行遍历将位置和保存在map映射中,最后按顺序输出map集合中的值。

    至于如何遍历,我是依次尝试了宽度优先遍历和深度优先遍历,当然这都是可以的。不过期间写错了很多次。在此总结以下在这道题目中犯得错误(逻辑错误):

  1. 同一树,根节点地址不变,却多次使用
  2. 同一映射,不经清空却多次添加
  3. 遍历时在队列和栈中添加进的节点不是当前节点(即写错节点名称)
  4. 栈溢出导致结果出错
  5. 对一个节点分配内存只能在同一函数中进行 //否则需要添加指针引用(*指针也需要引用)

。。。。

以下附上我的AC代码:

#include <cstdio>
#include <queue>
#include <iostream>
#include <vector>
#include <map>
#include <stack>
using namespace std;
struct Node{
    Node *left;
    Node *right;
    int  v;
    int k;
    Node():left(NULL),right(NULL){}
};
map<int,int> m;
void remove_tree(Node* u){
    if(u==NULL)return ;
    remove_tree(u->left);
    remove_tree(u->right);
    delete u;
}
int solve(Node *& u){//特别注意这一段
    int v;
scanf(
"%d", &v); if(v == -1){ u->v=0;return 0;} else { u->left = new Node(); u->right = new Node(); u->v = v; solve(u->left);//左子树 solve(u->right);//右子树 } return 1; } queue<Node*> q; //宽度优先遍历 void bfs(Node * u){ u->k=0; q.push(u); while(!q.empty()){ Node * node =q.front(); q.pop(); if(node->v)m[node->k] = m[node->k]+(node->v); if(node->left!=NULL&&node->left->v){node->left->k = (node->k)-1;; q.push(node->left);} if(node->right!=NULL&&node->right->v){node->right->k = (node->k )+ 1; q.push(node->right);} } } stack<Node*> s; //深度优先遍历:stl栈板 void dfs1(Node* u,int k){ u->k=k; s.push(u); while(!s.empty()){ Node *node=s.top(); s.pop(); if(node->left!=NULL&&node->left->v){node->left->k=(node->k)-1;s.push(node->left);} if(node->v)m[node->k] = m[node->k]+(node->v); if(node->right!=NULL&&node->right->v){node->right->k=(node->k)+1;s.push(node->right);} } } //深度优先遍历:递归版 void dfs(Node* u,int k){ // printf("%d ,%d ",u->v,k); if(u->v)m[k] = m[k]+(u->v); if(u->left!=NULL&&u->left->v)dfs(u->left,k-1); if(u->right!=NULL&&u->right->v)dfs(u->right,k+1); } int main(){ #ifdef DEBUG freopen("6.10.in","r",stdin); freopen("6.10.out","w",stdout); #endif int n = 0,r; Node *root=new Node() ; while((r=solve(root))){ printf("Case %d: ",++n); bfs(root); //*****************注意在一个树使用完毕之后一定要删除它 remove_tree(root); root=new Node();//注意要重新建一个根节点 int first=1; for(map<int,int>::iterator it = m.begin(); it!= m.end(); ++it){ if(!first)cout<<" ";else first=0; cout <<it->second; } m.clear();//使用完之后要清空 printf(" "); if(r)printf(" "); else break; } return 0; }
原文地址:https://www.cnblogs.com/Wade-/p/5759531.html