这道题我的思路是先通过递归构建树,然后进行遍历将位置和保存在map映射中,最后按顺序输出map集合中的值。
至于如何遍历,我是依次尝试了宽度优先遍历和深度优先遍历,当然这都是可以的。不过期间写错了很多次。在此总结以下在这道题目中犯得错误(逻辑错误):
- 同一树,根节点地址不变,却多次使用
- 同一映射,不经清空却多次添加
- 遍历时在队列和栈中添加进的节点不是当前节点(即写错节点名称)
- 栈溢出导致结果出错
- 对一个节点分配内存只能在同一函数中进行 //否则需要添加指针引用(*指针也需要引用)
。。。。
以下附上我的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; }