[代码分享]静态链表,接口仿照STL设计,操作未做封装
2013-04-22 23:13
218 查看
很久没有来CSDN,也很久没有写东西了。去年12月在OSCHINA注册了号,发了两段code。这次转过来,以便日后查阅。
连接:http://www.oschina.net/code/snippet_737017_16964
这是一段静态链表的实现,其间用到了一种简单的内存管理策略——空闲链表。
这段代码里的“静态”是一个预先分配好的 node array,实际情况下可能会是一个一次性申请的较大的memory block。
其实是在这段 node array上维护两个链表,一个used list,一个free list,即代码中的idata,和ifree。
完整代码及测试见:http://www.oschina.net/code/snippet_737017_16964
记得曾经在反《算法导论》的时候好像看到书中提到静态链表的实现问题,当时没有在意,直到去年写下这段代码的时候任然没有详细去看;今天翻出电子版一看,有近两页篇幅描述。
《算法导论》中的描述还是较为精炼的,文字不多,条理清晰,这里有一副原书中的插图,书中先讲了在没有指针的语言中如何表示指针和对象;
然后,话锋一转,在这样的情况下“Thus, it is useful to manage the storage of objects not currently used in the linked-list representation so that one can be allocated.”
然后书中也给出了伪代码:(要是早知道,我也那个夜晚也不用搞到两点了☺)
连接:http://www.oschina.net/code/snippet_737017_16964
这是一段静态链表的实现,其间用到了一种简单的内存管理策略——空闲链表。
这段代码里的“静态”是一个预先分配好的 node array,实际情况下可能会是一个一次性申请的较大的memory block。
其实是在这段 node array上维护两个链表,一个used list,一个free list,即代码中的idata,和ifree。
// 静态链表 的实现 #include <stdio.h> #define MAXN 16 // capacity of list. typedef int element; // element type. // define boolean type: typedef int bool; #define true -1 #define false 0 #define NPTR -1 // null pointer definition. can not between 0 to MAXN-1. typedef int pointer; #define DEBUGVAL(x) printf("%s: %d\n", #x, (x)); // a macro for debug. struct __node { element data; pointer next; }SLList[MAXN]; pointer ifree, idata; #define nextof(p) SLList[p].next #define dataof(p) SLList[p].data #define _alloc(d) ifree; dataof(ifree)=(d); ifree != NPTR ? ifree=nextof(ifree) : NPTR #define _free(p) nextof(p)=ifree; ifree = p void init() { int i; ifree = 0; idata = NPTR; for( i=0; i < MAXN-1; i++) nextof(i) = i+1; nextof(i) = NPTR; } // clear all nodes. void clear() { init(); } // push val to front. bool push_front(element val) { pointer tmp, np; if( ifree != NPTR ) { np = _alloc(val); nextof(np) = idata; idata = np; return true; } return false; } // push val to end of list. bool push_back(element val) { if( idata == NPTR ) { // 空表,直接写入 idata = _alloc(val); nextof(idata) = NPTR; return true; } if( ifree != NPTR ) { // 非空,先找到最后一个节点 pointer last = idata, np; while( nextof(last) != NPTR ) last = nextof(last); np = _alloc(val); nextof(np) = NPTR; nextof(last) = np; return true; } return false; } // insert val to after p pointed node. bool insert_after(pointer p, element val) { if( ifree != NPTR && p != NPTR ) { pointer pn = _alloc(val); nextof(pn) = nextof(p); nextof(p) = pn; return true; } return false; } // insert to the position in front of p. bool insert(pointer ptr, element val) { if( ifree == NPTR ) return false; // 没有结点,直接返回 if( ptr == idata ) { // 有一个节点 pointer np = _alloc(val); nextof(np) = idata; idata = np; return true; } else { // 其他情况,先找 ptr 的前驱,再插入 pointer p = idata; while( p != NPTR ) { if( nextof(p) == ptr ) { // find p -- the prev node of ptr. return insert_after(p, val); // insert val after p. } p = nextof(p); } } return false; } // find element, return the prev node pointer. pointer find_prev(element val) { pointer p = idata; while( p != NPTR ) { if( dataof( nextof(p) ) == val ) return p; p = nextof(p); } return NPTR; } // find element, return the node pointer. pointer find(element val) { pointer p = idata; while( p != NPTR ) { if( dataof(p) == val ) return p; p = nextof(p); } return NPTR; } // pop front element. void pop_front() { if( idata != NPTR ) { // 将 data list 最前面的节点 移到 free list 上 #if 0 pointer p = idata; idata = nextof(idata); // idata = nextof(idata); nextof(p) = ifree; // SLList[p].next = ifree; ifree = p; #else pointer p = idata; idata = nextof(idata); _free(p); #endif } } // pop back element. void pop_back() { if( idata == NPTR ) return; if( nextof(idata) == NPTR ) { // only 1 node. nextof(idata) = ifree; ifree = idata; idata = NPTR; } else { // 找到最后一个节点 p,以及它的前驱 q. // TODO: find the lase nod p, and it's perv node q. pointer p = idata, q; while( nextof(p) != NPTR ) { q = p; p = nextof( p ); } // remove *p to free list, update nextof(q) to NPTR. nextof(p) = ifree; ifree = p; nextof(q) = NPTR; } }
完整代码及测试见:http://www.oschina.net/code/snippet_737017_16964
记得曾经在反《算法导论》的时候好像看到书中提到静态链表的实现问题,当时没有在意,直到去年写下这段代码的时候任然没有详细去看;今天翻出电子版一看,有近两页篇幅描述。
《算法导论》中的描述还是较为精炼的,文字不多,条理清晰,这里有一副原书中的插图,书中先讲了在没有指针的语言中如何表示指针和对象;
然后,话锋一转,在这样的情况下“Thus, it is useful to manage the storage of objects not currently used in the linked-list representation so that one can be allocated.”
然后书中也给出了伪代码:(要是早知道,我也那个夜晚也不用搞到两点了☺)
ALLOCATE-OBJECT() if free = NIL then error "out of space" else x ← free free ← next[x] return x
FREE-OBJECT(x) 1 next[x] ← free 2 free ← x
相关文章推荐
- [代码分享]静态链表,接口仿照STL设计,操作未做封装
- [代码分享]静态链表,接口仿照STL设计,操作未做封装
- 应用程序操作NorFlash示例代码分享(norflash接口使用方法)
- 分享一个完整的SAP RFC调用接口封装
- 基于口令和证书认证(TrueLicense)的接口调用工具库的封装设计 By 嗡汤圆
- C++ stl队列Queue用法介绍:删除,插入等操作代码举例
- 系统操作日志设计-代码实现
- iOS-基于AVPlayer的视频播放器代码封装-0-需求分析与框架设计阶段
- 用面向对象封装操作操作系统之跨平台基础框架设计(一)
- 一个封装好的CSV文件操作C#类代码
- [学习记录]接口的封装与设计之文件读写
- 转整理分享C#通过user32.dll模拟物理按键操作的代码
- 基于JQuery,博客、微博分享代码的封装。
- 在 Java2中,有一套设计优良的接口和类组成了Java集合框架Collection,使程序员操作成批的数据或对象元素极为方便。这些接口和类有很多对抽象数据类型操作的API,而这是我们常用的且在数据结
- 以MyBatis+SpringMVC3.0实现的,借鉴了Hibernate设计思想,采用封装、抽象、继承的设计思想,做到了数据与相应的操作的高内聚低耦合的实现
- 微信蓝牙demo服务器官方代码操作——配置接口配置
- 仿照csdn左面的菜单的ASP+数据库无限级树菜单代码分享
- 求高手分享帐号通一键登录淘宝、腾讯、新浪、和各大门户网站接口代码
- 常用代码备忘录(封装 Apache Commons 的 DbUtils 实现的数据库操作工具类)-DBUtil.java
- Java微信公众平台接口封装源码分享