• 深深深深深深入虎穴


    深入虎穴

    比起之前的AI,这题更倾向对数据结构的理解和应用。只要抓住树的逻辑结构,并选择合适的存储结构,代码的实现并不困难
    100行都没到呢,AI都几百行了!

    代码实现

    点击跳转:7-2 深入虎穴 (30 分)

    心得

    从逻辑结构入手

    首先最直观的感受,是一个逻辑结构对一个算法的重要性
    当确定了逻辑结构,解决问题就有了思路,不会手足无措。当我们知道这个“虎穴”应该用树存储之后,要考虑的问题就是应该用什么存储结构来表示这个树,而当存储结构定下来后,就真正进入代码实现的阶段。从结构的定义到函数的操作,一步一步往下走,一个问题自然而然就能得到解决。

    灵活的存储结构

    明明是一棵树,我们却没有用带两个指针的结点而是用数组存储,用一个并不匹配的存储结构表示其逻辑结构,好神奇的一件事。
    不论是被否决的邻接表,还是现在的数组,都可以用来表示一棵树。所以当选择存储结构的时候,思维不能被局限了,逻辑结构和存储结构并非要完全一致
    其次,我们将每个结点的指针域所指向的结构,从链表变为了数组。一开始的链表其实也可以解题,但是链表操作麻烦,而且我懒所以不喜欢链表,那么就思考能不能避免链表的出现呢?既然都是一维的数据,我们实际上是可以选择一维数组代替单链表。灵活地选择更为熟悉的结构,对我们的编程有很大的帮助。

    指针的空间分配

    这个程序虽然没有链表,但是结点的指针域还是用到了指针。而很多bug都来源于这些指针。(所以才不喜欢链表)
    其中最常见的,是因为指针没有被分配空间,从而导致非法访问。例如程序中的结点定义

    //结点定义
    typedef struct {
    	int num;	//门后面的门的总数
    	int *p;		//指向门之后的门的编号所组成的数组
    }node;
    

    指针域中定义了一个指针,没有指定空间,所以一直是野指针。
    野指针就是坏蛋,是要尽量去避免的。
    在程序中,当我们输入门后面的路数量后,会给p开辟一个数组空间,然后输入数值。这个时候p就指向数组的首地址,并不是野指针呀。
    这个时候就要考虑特殊情况,比如门后面的路为0的时候。这个时候我们不需要申请数组,所以实际上是不做操作,这个时候就需要额外将指针变为空指针。
    空指针会比野指针友好很多。

    	for (int i = 1; i <= n; i++) {
    		......
    		if (a[i].num != 0) {	//如果不为0,分配空间并循环输入
    			......
    		}
    		else {		//如果门后没有路,就将指针置空
    			a[i].p = NULL;
    		}
    	}
    
  • 相关阅读:
    区块链价值
    区块链路线图
    Hyperledger Fabric Orderer节点启动
    使用 Docker 部署 Grafana + Prometheus 监控 MySQL 数据库
    CentOS 7.x 安装 Docker-Compose
    关于 Abp 替换了 DryIoc 框架之后的问题
    [Abp 源码分析]十七、ASP.NET Core 集成
    使用 DryIoc 替换 Abp 的 DI 框架
    《CLR Via C#》读书笔记:27.计算限制的异步操作
    《CLR Via C#》读书笔记:26.线程基础
  • 原文地址:https://www.cnblogs.com/luoyang0515/p/10771231.html
Copyright © 2020-2023  润新知