编译原理,内存管理和垃圾回收

把所有指针集中到一起,构成图结构,放在数组里。如何写链表呢?C语言实现的数据结构,习惯把next指针放在data旁边。要改变这一现状。先分配一块内存记录数据,再从图结构里添加一个节点。节点和内存块一一对应。怎样表示图结构?每个节点有3个成员,分别是 内存块的首地址、子节点、兄弟节点。

空白节点构成一个链表,首地址=NULL,子节点当做next,兄弟节点待定。是否应该用C语言的共用体实现?节点保存在数组中,遍历时,从数组的第一个元素开始,a[0]是根节点,不能删除。所有空闲的堆内存在数组中都有对应的节点?这也是如何表示空闲内存的方法,每块空闲内存都对应一个节点,这些节点组成链表。分配内存时,依次扫描链表,找到适当大小的一块空闲内存。

空白节点和空闲内存不同,空闲内存对应于节点数组中的有效节点,其特点是首地址项≠NULL;而空白节点是数组中尚未使用的项目,本来应该指向堆内存的首地址=NULL。

当所有指针集中到一起后,可以进行指针的搜索。以前必须用双链表解决的问题,现在用单链表。一个指针,从A指向B,在A处能知道它指向了B,但是在B处却不知道谁指向了自己。以前遇到这类问题,用两个指针解决,即单链表变成双链表。有了指针搜索功能后,不必这样了。

垃圾回收的标准是,某节点,没有节点指向它,则该节点为可回收节点。应该释放该节点,和它对应的堆内存。我想到一个笨方法,由于0号节点表示根节点,所以跳过它,从1号节点开始,如果1号节点的首地址≠NULL,这表明它是一个有效节点,遍历节点数组,看有没有哪个指针指向它,如果有则进行下一个节点,如果没有则按照垃圾节点处理。处理完节点数组中的所有节点后,即完成了一次垃圾回收。这个方法太慢了,若节点数组中有N项,则需N2次操作。不过每次操作倒是时间都不长,即使这样也不成,太慢。

方法二,把指针数组里的有效节点都加入哈希表,然后就能快速地判断某地址在不在其中。这个方法肯定能快不少。时间复杂度从n2降到了2n。

关于0号节点有没有兄弟节点,我想,完全可以有。画出图来,它们是几个独立的图结构,都有效。没有理由拒绝这个功能。

不能删除0号节点,也不应该指向0号节点。为什么?因为它就是这么特殊。

上文中总是叫“节点数组”,应该叫指针段,并期待CPU能支持这个段寄存器。到时候,有代码段、指针段、数据段(纯数据,没有指针)、栈也是一个段。输入法里都没有“指针段”这个词,看来我又超前了。

数据结构的课本里没有兄弟节点,着重讲解一下。设节点A有3个子节点b c d,则b c d是兄弟关系,它们构成一个链表,A的子节点是b,并且由b指出所有的b c d。节点数组是一个3列多行的表,3列分别是(堆内存中的首地址 子节点 兄弟节点)。设计中它们应该是64+32+32比特,设想不会有超过232个节点出现。这一想法是为了省内存,如果不在乎,都用64比特也可以。在数组中表示链表、图等结构,子节点和兄弟节点中记录的是绝对地址还是相对地址?采用绝对地址速度更快,采用相对地址(即数组下标)便于理解,但速度略慢,这是p和a[i]的速度差。另外一点不同,采用相对地址的节点数组可以复制、移动,绝对地址则不行。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值