算法竞赛入门经典:第六章 数据结构基础 6.7层次遍历

来源:互联网 发布:网页游戏优化器 编辑:程序博客网 时间:2024/05/16 16:09
/*层次遍历:输入一颗二叉树,你的任务是按从上到下、从左到右的顺序输出各个节点的值。每个节点都按照从根节点到它的移动序列给出(L表示左,R表示右)。在输入中,每个节点的左括号和右括号之间没有空格,相邻节点之间用一个空格隔开。每棵树的输入用一对空括号()结束(这对括号本身不代表一个节点)注意:如果从根到某个叶节点的路径上有的节点没有在输入中给出,或者给出了超过一次,应当输出-1.节点个数不超过256输入:(11,LL) (7,LLL) (8,R) (5,) (4,L) (13,RL) (2,LLR) (1,RRR) (4,RR) ()(3,L) (4,R) ()输出:5 4 8 11 13 4 7 2 1-1关键:如何建立这颗二叉树,可以在建树的过程中,写上LL等东西,后面再给元素赋值,这样需要三次遍历建树以什么来终止?不能提前建树,必须每给定一个节点建立一个*/#include <stdio.h>#include <stdlib.h>#include <string.h>#define MAXSIZE 1024int failed;typedef struct TNode{int v;struct TNode* left,*right;//不能写成Node* 的原因是此时Node类型还没有定义完int have_value;//是否被赋值}Node;Node* root;//根节点Node* newnode(){Node* node = (Node*)malloc(sizeof(Node));if(node)//要判断是否申请内存成功{node->have_value = 0;node->left = node->right = NULL;//初始时,没有左右孩子}return node;}void addnode(int v,char* str){int iLen = strlen(str);Node* node = root;//每次从根节点开始循环,用全局变量根节点来建立遍历的起始位置for(int i = 0; i < iLen ; i++){if('L' == str[i]){if(!node->left)//用node->left==NULL判断防止重复建节点{node->left = newnode();}node = node->left;}else if('R' == str[i]){if(!node->right){node->right = newnode();}node = node->right;}}//if(1 == node->have_value)//已经赋值,表示输入有错,不能用1,因为有的不是用1来赋值的if(node->have_value){failed = 1;}node->v = v;node->have_value = 1;}int ans[MAXSIZE];bool bfs(){Node* queue[MAXSIZE];int front = 0,rear = 1;//模拟队列queue[front] = root;int n = 0;while(front < rear){//ans[n++] = queue[front]->v;Node* u = queue[front++];if(!u->have_value)//有节点没有被赋值,出错{printf("%d\n",-1);return false;}if(u->left){queue[rear++] = u->left;}if(u->right){queue[rear++] = u->right;}ans[n++] = u->v;}for(int i = 0 ; i < n ; i++){printf("%d ",ans[i]);}return true;}void remove_tree(Node* node){if(!node){return;}remove_tree(node->left);remove_tree(node->right);free(node);//记住一定要释放完子节点才能释放该节点本身}int process(){char str[MAXSIZE];//remove_tree(root);//一定要释放内存root = newnode();//创建根节点for(; ;){if(1 != scanf("%s",str))//整个输入结束{return 0;}if(!strcmp(str,"()")){break;}int v;//sscanf(&str[1],"%d",v);//读入节点的值,把指向字符的指针看成字符串 &str[1] = "11,LL)",sscanf可以看做将字符串地址去掉后的普通输入sscanf(&str[1],"%d",&v);addnode(v,strchr(str,',') + 1);//strch(str,',') = "LL)"}bfs();remove_tree(root);return 1;}int main(int argc,char* argv[]){process();system("pause");return 0;}

0 0
原创粉丝点击