内存自管理的链表
来源:互联网 发布:final 定义数组 编辑:程序博客网 时间:2024/06/05 04:10
</pre></h1><p style="text-align: left; word-wrap: break-word; margin: 10px auto;"><span style="white-space: pre;"></span> 编程时会经常使用到链表这种结构,数组与链表这两种数据结构的区别以及优点不再赘言。在链表频繁使用时,可能会遇到这种问题,那就是可能要频繁的申请和释放内存,这样可能会造成内存碎片,对于很多程序是不希望看到的。那我在这里介绍我这两天写的一种链表,它能够消除内存频繁分配和释放、使用内存不连续的特点,当然水平有限,希望各位朋友提出宝贵意见,我能把这个数据结构和算法实现的更好,可供大家参考。</p><h2 style="padding:0px 0px 0px 20px; margin:0px; font-family:'ms shell dlg'; line-height:28px">(一)介绍一下普通的链表结构</h2><div><pre name="code" class="cpp">//节点的数据结构struct HNode{ void* data; //此节点所存放的对象的地址 HNode* next; HNode* last;};//链表的数据结构struct HList{ HNode* header; HNode* tail;};int hlist_empty(HList& list);int hlist_clear(HList& list);int hlist_push_back(HList& list, void* data);int hlist_push_front(HList& list, void* data);int hlist_insert(HList& list, void* data1, void* data2);int hlist_delete(HList& list, void* data);
简单链表算法的实现:
#pragma once#include "stdafx.h"#include "list.h"//链表的初始化操作int hlist_empty(HList& list){ list.header = list.tail = 0; return 1;}//链表的清空操作,释放所有内存int hlist_clear(HList& list){ HNode* node = list.header; HNode* next; while (0 != node) { next = node->next; delete node; node = next; } return 1;}int hlist_push_back(HList& list, void* data){ HNode* newNode = new HNode; newNode->data = data; newNode->next = 0; newNode->last = list.tail; if (0 == list.header)//空链表 { list.header = list.tail = newNode; } else//非空链表 { list.tail->next = newNode; list.tail = newNode; } return 1;}int hlist_push_front(HList& list, void* data){ HNode* newNode = new HNode; newNode->data = data; newNode->last = 0; newNode->next = list.header; if (0 == list.header)//空链表 { list.header = list.tail = newNode; } else { list.header->last = newNode; list.header = newNode; } return 1;}int hlist_insert(HList& list, void* data1, void* data2){ bool find = false; HNode* node = list.header; HNode* next; while (0 != node) { next = node->next; if(node->data == data1) { HNode* newNode = new HNode; newNode->data = data2; newNode->last = node; newNode->next = next; node->next = newNode; if (0 != next) { next->last = newNode; } else { list.tail = newNode; } find = true; break; } node = next; } if(find) return 1; return 0;}int hlist_delete(HList& list, void* data){ HNode* node = list.header; HNode* next; bool find = false; while (0 != node) { next = node->next; if(data == node->data) { if (node->last == 0 && node->next == 0) { delete node; list.header = list.tail = 0; } else if(node->last == 0 && node->next != 0) { delete node; list.header = next; } else if(node->last != 0 && node->next == 0) { list.tail = node->last; list.tail->next = 0; delete node; } else { node->last->next = next; node->next->last = node->last; delete node; } find = true; break; } node = next; } if (find) { return 1; } return 0;}
(二)内存自管理的链表
上边是用C语言实现的最简单的数据结构和算法了。下面介绍避免内存碎片的链表的数据结构和使用方法。
#define Herror int//节点struct HNode{ void* data; HNode* next; HNode* last;};//内容链表typedef struct tag_HLink{ HNode* header; HNode* tail;}HLink;//删除链表typedef struct tag_HLinkDel{ HLink del; HNode** buf; unsigned int size; int index; int nBuf;}HLinkDel;//链表管理typedef struct tag_HList{ HLink link; HLinkDel link_del;}HList;Herror hlink_empty(HLink& link);Herror hlink_push_back(HLink& link, HNode* newNode);Herror hlink_push_front(HLink& link, HNode* newNode);Herror hlink_insert(HLink& link, void* data1, HNode* newNode);Herror hlink_delete(HLink& link, void* data, HNode* &nodeDel);Herror hlink_find(HLink& link, void* data, HNode* &nodeFind);Herror hlinkdel_empty(HLinkDel& linkdel, unsigned int size = 1024, int nBuf = 16);Herror hlinkdel_clear(HLinkDel& linkdel);Herror hlinkdel_pop(HLinkDel& linkdel, HNode* &node);Herror hlinkdel_push(HLinkDel& linkdel, HNode* node);Herror hlinkdel_alloc(HLinkDel& linkdel);Herror hlist_emtpy(HList& list);Herror hlist_clear(HList& list);Herror hlist_push_back(HList& list, void* data);Herror hlist_push_front(HList& list, void* data);Herror hlist_insert(HList& list, void* data1, void* data2);Herror hlist_delete(HList& list, void* data);
上述代码中的HNode节点与(一)中的一样。HLink与(一)的HList一样。而出现了一个HLinkDel和HList结构体,它是做什么用处呢?
像(一)中的链表,在添加或者插入新节点时才分配内存,删除节点也是立即释放此节点的内存。在进行一系列操作之后,链表中的节点在内存中的位置可能会很乱。如果频繁的使用插入和删除操作,则会产生内存碎片。在上边的代码中,我们用HLinkDel这个结构体来管理所有需要的内存。在创建链表时,会预先分配1024个节点的内存,即1024 * sizeof(HNode)个字节。这个数组首尾相连构成了HLinkDel成员del链表。即一个HList对象里,里边有两个链表,一个是真正的正在使用的link对象,另一个是管理着已经分配好内存的,等待着供link使用的linkdel的del链表。
(1)创建HList对象时,link为空,linkdel按照参数或者默认的为linkdel.buf创建16个HNode*的数组,全部赋值为0,再分配1024*sizeof(HNode)大小的内存块,其内存地址赋给linkdel.buf[0],内存块中的所有节点连接起来交给del链表。
(2)link增加或者插入节点时,从linkdel对象的del链表中取出一个节点,给link使用,当然del链表中去掉此节点。
(3)link删除一个节点时,把删除的节点交给linkdel对象,加入到它的del链表中。
(4)在使用了一段时间后,发现linkdel中的del链表已经空了,那么表明,之前分配的内存已经用完了,那么我们给linkdel.buf[1]再分配1024 * Sizeof(HNode) * 2 的内存,再给linkdel的del链表使用。
(5)在最终使用完后,直接将linkdel中的buf数组中指向的每个内存块释放,再释放buf数组,就可以了。
实现代码如下:
#pragma once#include "stdafx.h"#include "HList.h"//内容链表Herror hlink_empty(HLink& link){ link.header = 0;link.tail = 0;return 1;}Herror hlink_push_back(HLink& link, HNode* newNode){ newNode->last = link.tail;newNode->next = 0;if(link.tail == 0){link.tail = link.header = newNode;}else{link.tail->next = newNode;link.tail = newNode;}return 1;}Herror hlink_push_front(HLink& link, HNode* newNode){ newNode->last = 0;newNode->next = link.header;if (0 == link.header){link.header = link.tail = newNode;} else{link.header->last = newNode;link.header = newNode;}return 1;}Herror hlink_insert(HLink& link, void* data1, HNode* newNode){ bool find = false;HNode* node = link.header;HNode* next;while (0 != node){next = node->next;if(node->data == data1){find = true;newNode->last = node;newNode->next = node->next;node->next = newNode;if(0 == next){link.tail = newNode;}else{node->next->last= newNode;}break;}node = next;}if(find)return 1;return 0;}Herror hlink_delete(HLink& link, void* data, HNode* &nodeDel){ HNode* node = link.header;HNode* next;bool find = false;while (0 != node){next = node->next;if(data == node->data){find = true;nodeDel = node;/*if(next == 0){node->last->next = 0;}else{next->last = node->last;node->last->next = next;}*/if(0 == next && 0 == node->last){link.header = link.tail = 0;}else if (0 == next && 0 != node->last){node->last->next = 0;link.tail = node->last;}else if (0 != next && 0 == node->last){node->next->last = 0;link.header = node->next;}else{next->last = node->last;node->last->next = next;}break;}node = next;}return 1;}Herror hlink_find(HLink& link, void* data, HNode* &nodeFind){ bool find = false;HNode* node = link.header;HNode* next;while (0 != node){next = node->next;if(data == node->data){nodeFind = node; find = true;break;}node = next;}if(find)return 1;return 0;}//删除链表Herror hlinkdel_empty(HLinkDel& linkdel, unsigned int size, int nBuf){ hlink_empty(linkdel.del);linkdel.size = size;linkdel.nBuf = nBuf;linkdel.index = -1;linkdel.buf = new HNode*[nBuf];for (int i = 0; i < nBuf; i++){linkdel.buf[i] = 0;}hlinkdel_alloc(linkdel);return 1;}Herror hlinkdel_alloc(HLinkDel& linkdel){linkdel.index++;int n = linkdel.index;unsigned int len = linkdel.size * (1 << n);linkdel.buf[n] = new HNode[len];HNode* p;for (unsigned int i = 0; i < len; i++){p = linkdel.buf[n] + i;p->data = 0;p->next = p + 1;p->last = p - 1;}p = linkdel.buf[n];p[len-1].next = p[0].last = 0;linkdel.del.header = p;linkdel.del.tail = p + len - 1;return 1;}Herror hlinkdel_clear(HLinkDel& linkdel){ for (int i = 0; i < linkdel.nBuf; i++){delete []linkdel.buf[i];}delete []linkdel.buf;linkdel.buf = 0;hlink_empty(linkdel.del);linkdel.index = -1;linkdel.nBuf = 0;linkdel.size = 0;return 1;}Herror hlinkdel_pop(HLinkDel& linkdel, HNode* &node){ HLink& del = linkdel.del;if(del.header != 0){node = del.header;if(del.tail == node){hlinkdel_alloc(linkdel);}else{del.header->next->last = 0;del.header = del.header->next;}}else if(del.header == 0){hlinkdel_alloc(linkdel);hlinkdel_pop(linkdel, node);}return 1;}Herror hlinkdel_push(HLinkDel& linkdel, HNode* node){ node->last = linkdel.del.tail;node->next = 0;linkdel.del.tail->next = node;linkdel.del.tail = node;return 1;}//链表管理Herror hlist_emtpy(HList& list){ hlink_empty(list.link);hlinkdel_empty(list.link_del);return 1;}Herror hlist_clear(HList& list){ hlinkdel_clear(list.link_del);return 1;}Herror hlist_push_back(HList& list, void* data){ HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data;hlink_push_back(list.link, newNode);return 1;}Herror hlist_push_front(HList& list, void* data){ HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data;hlink_push_front(list.link, newNode);return 1;}Herror hlist_insert(HList& list, void* data1, void* data2){ //产生新节点HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data2;//插入新节点hlink_insert(list.link, data1, newNode);return 1;}Herror hlist_delete(HList& list, void* data){ //在内容链表中删除此节点HNode* nodeDel = 0;hlink_delete(list.link, data, nodeDel);//在删除链表中加入此节点if(nodeDel != 0){hlinkdel_push(list.link_del, nodeDel);}else{return 0;}return 1;}
这两天全部时间都在写这个链表的代码了,从各方面我也考虑了很多,但是毕竟个人水平有限,希望大家多提修改意见,能让这个算法更好用。供更多人参考和使用。
提前感谢所有的建议和批评!
#pragma once#include "stdafx.h"#include "list.h"//链表的初始化操作int hlist_empty(HList& list){ list.header = list.tail = 0; return 1;}//链表的清空操作,释放所有内存int hlist_clear(HList& list){ HNode* node = list.header; HNode* next; while (0 != node) { next = node->next; delete node; node = next; } return 1;}int hlist_push_back(HList& list, void* data){ HNode* newNode = new HNode; newNode->data = data; newNode->next = 0; newNode->last = list.tail; if (0 == list.header)//空链表 { list.header = list.tail = newNode; } else//非空链表 { list.tail->next = newNode; list.tail = newNode; } return 1;}int hlist_push_front(HList& list, void* data){ HNode* newNode = new HNode; newNode->data = data; newNode->last = 0; newNode->next = list.header; if (0 == list.header)//空链表 { list.header = list.tail = newNode; } else { list.header->last = newNode; list.header = newNode; } return 1;}int hlist_insert(HList& list, void* data1, void* data2){ bool find = false; HNode* node = list.header; HNode* next; while (0 != node) { next = node->next; if(node->data == data1) { HNode* newNode = new HNode; newNode->data = data2; newNode->last = node; newNode->next = next; node->next = newNode; if (0 != next) { next->last = newNode; } else { list.tail = newNode; } find = true; break; } node = next; } if(find) return 1; return 0;}int hlist_delete(HList& list, void* data){ HNode* node = list.header; HNode* next; bool find = false; while (0 != node) { next = node->next; if(data == node->data) { if (node->last == 0 && node->next == 0) { delete node; list.header = list.tail = 0; } else if(node->last == 0 && node->next != 0) { delete node; list.header = next; } else if(node->last != 0 && node->next == 0) { list.tail = node->last; list.tail->next = 0; delete node; } else { node->last->next = next; node->next->last = node->last; delete node; } find = true; break; } node = next; } if (find) { return 1; } return 0;}
(二)内存自管理的链表
上边是用C语言实现的最简单的数据结构和算法了。下面介绍避免内存碎片的链表的数据结构和使用方法。
#define Herror int//节点struct HNode{ void* data; HNode* next; HNode* last;};//内容链表typedef struct tag_HLink{ HNode* header; HNode* tail;}HLink;//删除链表typedef struct tag_HLinkDel{ HLink del; HNode** buf; unsigned int size; int index; int nBuf;}HLinkDel;//链表管理typedef struct tag_HList{ HLink link; HLinkDel link_del;}HList;Herror hlink_empty(HLink& link);Herror hlink_push_back(HLink& link, HNode* newNode);Herror hlink_push_front(HLink& link, HNode* newNode);Herror hlink_insert(HLink& link, void* data1, HNode* newNode);Herror hlink_delete(HLink& link, void* data, HNode* &nodeDel);Herror hlink_find(HLink& link, void* data, HNode* &nodeFind);Herror hlinkdel_empty(HLinkDel& linkdel, unsigned int size = 1024, int nBuf = 16);Herror hlinkdel_clear(HLinkDel& linkdel);Herror hlinkdel_pop(HLinkDel& linkdel, HNode* &node);Herror hlinkdel_push(HLinkDel& linkdel, HNode* node);Herror hlinkdel_alloc(HLinkDel& linkdel);Herror hlist_emtpy(HList& list);Herror hlist_clear(HList& list);Herror hlist_push_back(HList& list, void* data);Herror hlist_push_front(HList& list, void* data);Herror hlist_insert(HList& list, void* data1, void* data2);Herror hlist_delete(HList& list, void* data);
上述代码中的HNode节点与(一)中的一样。HLink与(一)的HList一样。而出现了一个HLinkDel和HList结构体,它是做什么用处呢?
像(一)中的链表,在添加或者插入新节点时才分配内存,删除节点也是立即释放此节点的内存。在进行一系列操作之后,链表中的节点在内存中的位置可能会很乱。如果频繁的使用插入和删除操作,则会产生内存碎片。在上边的代码中,我们用HLinkDel这个结构体来管理所有需要的内存。在创建链表时,会预先分配1024个节点的内存,即1024 * sizeof(HNode)个字节。这个数组首尾相连构成了HLinkDel成员del链表。即一个HList对象里,里边有两个链表,一个是真正的正在使用的link对象,另一个是管理着已经分配好内存的,等待着供link使用的linkdel的del链表。
(1)创建HList对象时,link为空,linkdel按照参数或者默认的为linkdel.buf创建16个HNode*的数组,全部赋值为0,再分配1024*sizeof(HNode)大小的内存块,其内存地址赋给linkdel.buf[0],内存块中的所有节点连接起来交给del链表。
(2)link增加或者插入节点时,从linkdel对象的del链表中取出一个节点,给link使用,当然del链表中去掉此节点。
(3)link删除一个节点时,把删除的节点交给linkdel对象,加入到它的del链表中。
(4)在使用了一段时间后,发现linkdel中的del链表已经空了,那么表明,之前分配的内存已经用完了,那么我们给linkdel.buf[1]再分配1024 * Sizeof(HNode) * 2 的内存,再给linkdel的del链表使用。
(5)在最终使用完后,直接将linkdel中的buf数组中指向的每个内存块释放,再释放buf数组,就可以了。
实现代码如下:
#pragma once#include "stdafx.h"#include "HList.h"//内容链表Herror hlink_empty(HLink& link){ link.header = 0;link.tail = 0;return 1;}Herror hlink_push_back(HLink& link, HNode* newNode){ newNode->last = link.tail;newNode->next = 0;if(link.tail == 0){link.tail = link.header = newNode;}else{link.tail->next = newNode;link.tail = newNode;}return 1;}Herror hlink_push_front(HLink& link, HNode* newNode){ newNode->last = 0;newNode->next = link.header;if (0 == link.header){link.header = link.tail = newNode;} else{link.header->last = newNode;link.header = newNode;}return 1;}Herror hlink_insert(HLink& link, void* data1, HNode* newNode){ bool find = false;HNode* node = link.header;HNode* next;while (0 != node){next = node->next;if(node->data == data1){find = true;newNode->last = node;newNode->next = node->next;node->next = newNode;if(0 == next){link.tail = newNode;}else{node->next->last= newNode;}break;}node = next;}if(find)return 1;return 0;}Herror hlink_delete(HLink& link, void* data, HNode* &nodeDel){ HNode* node = link.header;HNode* next;bool find = false;while (0 != node){next = node->next;if(data == node->data){find = true;nodeDel = node;/*if(next == 0){node->last->next = 0;}else{next->last = node->last;node->last->next = next;}*/if(0 == next && 0 == node->last){link.header = link.tail = 0;}else if (0 == next && 0 != node->last){node->last->next = 0;link.tail = node->last;}else if (0 != next && 0 == node->last){node->next->last = 0;link.header = node->next;}else{next->last = node->last;node->last->next = next;}break;}node = next;}return 1;}Herror hlink_find(HLink& link, void* data, HNode* &nodeFind){ bool find = false;HNode* node = link.header;HNode* next;while (0 != node){next = node->next;if(data == node->data){nodeFind = node; find = true;break;}node = next;}if(find)return 1;return 0;}//删除链表Herror hlinkdel_empty(HLinkDel& linkdel, unsigned int size, int nBuf){ hlink_empty(linkdel.del);linkdel.size = size;linkdel.nBuf = nBuf;linkdel.index = -1;linkdel.buf = new HNode*[nBuf];for (int i = 0; i < nBuf; i++){linkdel.buf[i] = 0;}hlinkdel_alloc(linkdel);return 1;}Herror hlinkdel_alloc(HLinkDel& linkdel){linkdel.index++;int n = linkdel.index;unsigned int len = linkdel.size * (1 << n);linkdel.buf[n] = new HNode[len];HNode* p;for (unsigned int i = 0; i < len; i++){p = linkdel.buf[n] + i;p->data = 0;p->next = p + 1;p->last = p - 1;}p = linkdel.buf[n];p[len-1].next = p[0].last = 0;linkdel.del.header = p;linkdel.del.tail = p + len - 1;return 1;}Herror hlinkdel_clear(HLinkDel& linkdel){ for (int i = 0; i < linkdel.nBuf; i++){delete []linkdel.buf[i];}delete []linkdel.buf;linkdel.buf = 0;hlink_empty(linkdel.del);linkdel.index = -1;linkdel.nBuf = 0;linkdel.size = 0;return 1;}Herror hlinkdel_pop(HLinkDel& linkdel, HNode* &node){ HLink& del = linkdel.del;if(del.header != 0){node = del.header;if(del.tail == node){hlinkdel_alloc(linkdel);}else{del.header->next->last = 0;del.header = del.header->next;}}else if(del.header == 0){hlinkdel_alloc(linkdel);hlinkdel_pop(linkdel, node);}return 1;}Herror hlinkdel_push(HLinkDel& linkdel, HNode* node){ node->last = linkdel.del.tail;node->next = 0;linkdel.del.tail->next = node;linkdel.del.tail = node;return 1;}//链表管理Herror hlist_emtpy(HList& list){ hlink_empty(list.link);hlinkdel_empty(list.link_del);return 1;}Herror hlist_clear(HList& list){ hlinkdel_clear(list.link_del);return 1;}Herror hlist_push_back(HList& list, void* data){ HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data;hlink_push_back(list.link, newNode);return 1;}Herror hlist_push_front(HList& list, void* data){ HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data;hlink_push_front(list.link, newNode);return 1;}Herror hlist_insert(HList& list, void* data1, void* data2){ //产生新节点HNode* newNode;hlinkdel_pop(list.link_del, newNode);newNode->data = data2;//插入新节点hlink_insert(list.link, data1, newNode);return 1;}Herror hlist_delete(HList& list, void* data){ //在内容链表中删除此节点HNode* nodeDel = 0;hlink_delete(list.link, data, nodeDel);//在删除链表中加入此节点if(nodeDel != 0){hlinkdel_push(list.link_del, nodeDel);}else{return 0;}return 1;}
这两天全部时间都在写这个链表的代码了,从各方面我也考虑了很多,但是毕竟个人水平有限,希望大家多提修改意见,能让这个算法更好用。供更多人参考和使用。
提前感谢所有的建议和批评!
- 内存自管理的链表
- Keil自带的操作系统RTX内核---内存管理分析
- 内核如何管理你的内存(转自melody_lu123)
- Linux内存管理基本概念(转载自董的博客)
- 内存管理(转自JianglongHuang)
- 自启动的管理
- 使用链表管理内存
- C++的内存管理(转载自:http://blog.csdn.net/bizhu12/article/details/6668834)
- android自带的内存memory和第三方外部存储disk管理
- [内存管理]linux X86_64处理器的内存布局图(转自:http://blog.csdn.net/younger_china/article/details/16829687)
- 一个基于链表的内存管理方案
- 一个基于链表的内存管理方案
- 基于链表的方法实现静态内存管理
- 内存管理--内存的简介
- EJB自管理的事务
- 管理的最高境界”三自”
- linxu 自启动的管理
- 管理android应用的自启动应用---自启动管理
- nagios监控sqlserver2005镜像
- C# 中的委托和事件
- 节后回来第一日被解雇
- PowerDesigner(PowerDesigner15.1.0.2850)下载、安装以及破解
- welcome-file-list元素
- 内存自管理的链表
- 大智慧快捷键
- 搬水果(九度oj)
- 特殊分类账+信息结构实现进销存
- 水晶报表取oracle数据中文乱码
- 学习方法:三少三多
- ubuntu最新源
- SVN 配置文件说明
- sql server 2008 ,存储过程[IS2120@BG57IV3]