zoukankan      html  css  js  c++  java
  • UVA

    /*
      收获(详细内容见入门经典P151-155)
      
      1. 本题用于出入输入数据的函数 read_input 的书写方法,很值得学习
      
      2. 关于sscanf函数:
      http://www.cnblogs.com/kex1n/archive/2011/06/09/2076501.html
      
      3. C语言中字符串的灵活性:
      可以把任意“指向字符的指针” 看作字符串,从该位置开始,直到字符''
      
      4. 利用 strchr 截取字符串
    
      5. 利用队列实现树的层次遍历(宽度优先遍历,BFS) 
      
      6. 关于内存泄漏问题的处理方法: 释放二叉树,见P153
      
      7. 可用数组实现二叉树,用数组记录左右子节点的编号
      不过这样实现时,在静态申请数组,不方便释放内存,对此可采用内存池的方法,静态数组和空闲列表共同实现内存池
      内存池技术十分重要!!!
      
      8. 同时,借由入门经典下面的注释,简单搜索了解了"内存碎片"这一问题
    */


    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <vector>
    const int maxn = 256 + 10;
    char s[maxn];
    bool failed;
    using namespace std;
    
    //结点类型 
    struct Node
    {
    	bool have_value; //是否被赋值过
    	int v; //结点值
    	Node *left, *right; //左右子结点所对应的,指向结点类型的指针 
    	Node():have_value(false), left(NULL), right(NULL)
    	{
    	} 
    };
    Node *root; //二叉树的根结点 
    
    Node* newnode()
    {
    	return new Node();
    }
    
    void addnode(int v, char* s)
    {
    	int n = strlen(s);
    	Node *u = root; //从根结点开始往下走
    	for (int i = 0; i < n; i++)
    	if (s[i] == 'L')
    	{
    		if (u->left == NULL) u->left = newnode(); // 结点不存在,建立新结点
    		u = u->left; 
    	}
    	else if (s[i] == 'R')
    	{
    		if (u->right == NULL) u->right = newnode();
    		u = u->right;
    	}//忽略其他情况,即最后那个多余的右括号
    	if (u->have_value) failed = true; //已经赋过值,说明输入有误 
    	u->v = v;
    	u->have_value = true; //赋值后别忘记做标记 
    }
    
    void remove_tree(Node* u)
    {
    	if (u == NULL) return; //为了稳妥,提前判断 
    	remove_tree(u->left); //递归释放左子树 
    	remove_tree(u->right); //递归释放右子树 
    	delete u; //调用u的析构函数并释放u结点本身的内存 
    }
    bool read_input()
    {
    	failed = false;
    	remove_tree(root);
    	root = newnode(); //创建根结点 
    	
    	while (true)
    	{
    		if (scanf("%s", s) != 1) return false; //整个输入结束
    		if ( !strcmp(s, "()") ) break; //读到一组输入的结束,退出循环
    		int v;
    		sscanf(&s[1], "%d", &v); //********!!! 巧用了sscanf 和 C语言字符串的灵活性 
    		//读入结点值 
    		addnode(v, strchr(s, ',') + 1); //查找逗号,然后插入结点 
    	}
    	return true;
    }
    
    bool bfs(vector<int>&ans)
    {
    	queue<Node*> q;
    	ans.clear();
    	q.push(root);
    	while (!q.empty())
    	{
    		Node* u = q.front(); q.pop();
    		if (!u->have_value) return false; //如果结点没有被赋值过,表明输入有误
    		ans.push_back(u->v); //增加到输入队列尾部 
    		if (u->left != NULL) q.push(u->left); //把左子结点放入队列 (如果存在)
    		if (u->right != NULL) q.push(u->right); //把右子结点放入队列 (如果存在)
    	}
    	return true;
    }
    
    int main()
    {
    	while (true)
    	{
    		if (!read_input()) break;
    		vector<int>ans;
    		if (!failed && bfs(ans))
    		{
    			int len = ans.size();
    			for (int i = 0; i < len; i++)
    			printf("%d%c", ans[i], i == len - 1 ? '
    ': ' ');
    		}
    		else puts("not complete");
    	}
    	return 0;
    }


  • 相关阅读:
    Laravel实用小功能
    _initialize() 区别 __construct()
    PHP websocket之聊天室实现
    原来PHP对象比数组用更少的内存
    PHP协程
    mongodb数据库的导出与导入
    我理解的数据结构(一)—— 数组(Array)
    Swoole 源码分析——Server模块之Worker事件循环
    PHP面试:说下什么是堆和堆排序?
    我理解的数据结构(二)—— 栈(Stack)
  • 原文地址:https://www.cnblogs.com/mofushaohua/p/7789405.html
Copyright © 2011-2022 走看看