pat。
这个题目主要就是存储树以及遍历树。
解题心得:
1、可能对c++不是很熟,所以一开始我就循序渐进而用了教材上所给的结构体+指针来写。不过,确实有点晕。
2、我的树存储方法是:孩子存储法,也就是把每个节点都存在一个数组,然而后面链接着他的所有儿子。
3、BFS的原理就是树的层次遍历,所以我还是用了层次遍历,中间再加了一些题目所需要的语句。
4、需要注意的地方:
①:结构体指针用之前需要为它申请内存空间。。。。
②:需要手动把链表最后一个节点置空,否则虽然vs显示无法计算内存地址,但它还是会走到哪儿,然后终止程序。
③:由于我的存储方法是孩子存储法,所以后面循环的不是tree[myParent],而是他的第一个儿子。
struct node *firstChild;
firstChild = (struct node*)malloc(sizeof(struct node));
firstChild = tree[myParent].firstChild;
while(NULL != firstChild){
firstChild->level = level+1;//deeper and increment
myQueue.push(firstChild);
firstChild = firstChild->nextChild;
}
代码如下:
#include"stdio.h"
#include"string.h"
#include"math.h"
#include<iostream>
#include<vector>
#include<queue>
using namespace std;
#define INF 0x7FFFFFFF
//the storage structure of tree,you can choose other ways to store,also.
typedef struct node{
int value;
int level;
struct node *nextChild;
}*Node;
struct PTree{
int parent;
struct node *firstChild;
};
vector<struct PTree> tree;
vector<int> nonLeafs;
queue<Node> myQueue;
//level traversal,that is BFS
void levelOrder(){
int leaf = 0;
struct node *parent;
//get the first node and push it into the queue.
parent = (struct node*)malloc(sizeof(struct node));
int currentStep = 0;
parent->value = tree[1].parent;
parent->nextChild = tree[1].firstChild;
parent->level = 0;
myQueue.push(parent);
while(!myQueue.empty()){ //loop if not empty
struct node *tempNode;
tempNode = (struct node*)malloc(sizeof(struct node));
tempNode = myQueue.front();
myQueue.pop();
//get the first node
int myParent = tempNode->value;
int level = tempNode->level;
//modify the level and leaf number
if(level > currentStep){
currentStep = level;
nonLeafs.push_back(leaf);
leaf = 0;
}
//modify key of leaf if it has no child.
if(tree[myParent].firstChild == NULL){
leaf++;
}
//get the second node and push it into the queue,not the first!
struct node *firstChild;
firstChild = (struct node*)malloc(sizeof(struct node));
firstChild = tree[myParent].firstChild;
while(NULL != firstChild){
firstChild->level = level+1;//deeper and increment
myQueue.push(firstChild);
firstChild = firstChild->nextChild;
}
}
//add the last node's leaf number.
nonLeafs.push_back(leaf);
}
int main(){
int nodes,nonLeafNodes;
while(scanf("%d%d",&nodes,&nonLeafNodes) != EOF){
tree.resize(nodes+1); //size from 1~nodes
for(int i = 1;i < nonLeafNodes+1;i++){
int parentNode,nodesSize;
scanf("%d%d",&parentNode,&nodesSize);
tree[parentNode].parent = parentNode;
struct node *tempNode;
tempNode = (struct node*)malloc(sizeof(struct node));
tree[parentNode].firstChild = NULL;
for(int j = 0;j < nodesSize;j++){
// concat the tree.
int tempChild;
scanf("%d",&tempChild);
if(j==0){
tempNode->value = tempChild;
tree[parentNode].firstChild = tempNode;
if(j == nodesSize -1){
tempNode->nextChild = NULL;
}
continue;
}
struct node *temp2Node;
temp2Node = (struct node*)malloc(sizeof(struct node));
temp2Node->value = tempChild;
tempNode->nextChild = temp2Node;
tempNode = temp2Node;
if(j == nodesSize -1){
tempNode->nextChild = NULL;
}
}
}
levelOrder(); //traversal
//print out
for(int i = 0;i < nonLeafs.size();i++){
if(i == nonLeafs.size()-1){
printf("%d",nonLeafs[i]);
}else{
printf("%d ",nonLeafs[i]);
}
}
}
return 0;
}
当然我觉得作为acm,其实可以不用用指针,网上看到一位大牛,然后他的方法并没有用链表,而是通过c++的stl库中工具完成,我觉得比我的好。
http://download.youkuaiyun.com/detail/anla_/9728778