通用链表的建立和使用
来源:互联网 发布:linux mac配置文件 编辑:程序博客网 时间:2024/05/29 07:26
点击打开链接链表是一种很基本的数据结构,也是一种很常用的数据结构。最近编写了几个小程序,多处用到链表,现在就在这里总结一下自己的思考和经验,也请诸位高手多多指教。
其实理解了结构体和指针之后,链表的建立和使用还是挺简单的,但是按照教科书上写的来用,我们常常会遇到一个问题,就是链表的结构是不可以通用的,要存储不同的数据,就要重写不同的结构,重写构造链表的函数,十分麻烦,那我们可不可以写一个通用的链表呢?当然是可以的,下面我就介绍一下这个通用链表的构建以及实用方法。
闲话不多说,我们首先要建立一个节点的结构体:
typedef struct node
{
//数据域
void* data;
//指针域
struct node* next;
}NODE,* p2NODE;
这个结构体的数据域只有一个void型的指针,void指针在使用的时候灵活性是很大的。
下面我们就看一下如何使用这个节点的结构构件一张链表。
我们在建立链表的时候需要有一个头节点,我们在这里定义一下:
p2NODE head = NULL;
我们这张链表的头节点是需要存储数据的,所以链表长度为0 的时候,head要指向NULL,下面我们就写一个函数,每调用一次这个函数,就会向这个链表新添加一个节点,这样循环调用一下,我们这个链表就可以建立起来了:
p2NODE add_to_list(p2NODE head, void* data, size_t data_size)
{
//创建节点并为节点分配空间
p2NODE new_node = NULL;
new_node = (p2NODE)malloc(sizeof(NODE));
memset(new_node, 0, sizeof(NODE));
//为数据域分配空间并填充数据
new_node->data = malloc(data_size);
memcpy(new_node->data, data, data_size);
//将新节点链接到链表(头插法)
new_node->next = head;
head = new_node;
return head;
}
这个函数需要我们传递三个参数,头节点地址p2NODE head,需要存储的数据的地址缓冲区的地址,需要强制转换成void*型,以及要存储数据的大小,由于采用头插法,每调用一次链表的头节点是要改变的,所以返回新的头节点,这样我们就可以用这个NODE结构体和函数构造我们的链表了,下面我们就写一个简单的测试函数,看看这张链表的使用方法:
我们建立一张长度为5 的链表,每一个节点存储一个字符型数据,由输入获得
结构体定义和函数声明我们可以写在linklist.h 这个头文件中
#include "linklist.h"
int main(int argc, char* argv[])
{
char c;
p2NODE head = NULL;
p2NODE p = NULL;
int i = 0;
for(i=0;i<5;i++)
{
printf("请输入字符:");
fflush(stdout);
scanf("%c", &c);
head = add_to_list(head, (void*)&c, sizeof(char));
}
p = head;
while(p != NULL)
{
printf("%c\n", *(char*)(p->data)); //注意这里,p->data是一个void*,我们必须把它转换为相应类型的指针再取值
p = p->next;
}
return 0;
}
通过这样一个简单的测试函数,这张链表的使用方法已经很明了了吧,这里的数据缓冲区char c可以替换为其他的数据类型以及自己定义的结构体,只要建立链表时传入相应的sizeof()就行,当然上面的测试函数还有一个很大的错误,就是没有释放链表空间,这样我们需要些一个释放函数:
p2NODE free_list(p2NODE head)
{
p2NODE p = NULL;
while(head != NULL)
{
p = head->next;
free(head->data);
free(head);
head = p;
}
return head;
}
传入head释放链表,返回最后的head是为了将释放掉的链表的头节点指向NULL;
我写的linklist.c linklist.h的源代码我已经上传,下面是连接地址,有图方便的同学下载下来包含以下就可以直接用了
通用链表源代码
http://download.csdn.net/detail/aden_king/3875453
- 通用链表的建立和使用
- 数据结构-邻接链表的建立和使用
- 建立一个真机和模拟器通用的framework
- 字典类表的建立和使用
- 关于通用双向链表的使用
- TortoiseSVN的建立和使用
- tags的建立和使用
- Annotation 的建立和使用
- ServerSocket的建立和使用
- 联想电脑快捷键的使用和通用设置
- 建立通用语言:业务流程和工作流
- 数据库(2):配置数据的缓存建立方法,建立通用表模型
- oracle数据库链路的建立和使用
- oracle数据库链路的建立和使用
- SQL临时表建立和使用的一个例子
- 使用sqlite3.exe建立数据库和表结构的方法
- 链表的建立、插入和删除
- 链表的建立、插入和删除
- checkbox选中的值在翻屏时会跳来跳去
- dedecms模板定制之如何自定义标签
- java static
- 还是索引
- _gcvt(),_ecvt(),_fcvt()参数意义及区别 08.12.01
- 通用链表的建立和使用
- 文件内容拷贝
- iPhone之IOS5内存管理(ARC技术概述)
- iPhone之随机数的生成
- 软件调试 笔记1
- iPhone之网络编程初体验-简单的聊天程序
- iPhone之使用Cocos2d来开发简单的IPhone游戏教程
- Ubuntu 11.10源
- 插入排序