C语言实现一个泛型容器
2015-06-07 00:36
417 查看
用C语言实现一个容器,可以装字符串、字符、数字、二进制数据, 其中每一个被装进的数据要附带一个唯一识别码( uid )。
能遍历容器内数据节点,根据uid删除节点,打印节点。
我的解决方案:使用单链表,结构体里定义各数据类型,用一个标志位来标记数据类型,可以实现每个节点都能具有任意数据类型。
/**
******************************************************************************
* @file list.h
* @author summer
* @version V1.0
* @date 2015-05-25
* @brief C语言实现一个泛型容器
/**
******************************************************************************
* @file list.c
* @author summer
* @version V1.0
* @date 2015-05-25
* @brief C语言实现一个泛型容器
测试程序
#include <stdio.h>
#include <stdlib.h>
#include"list.h"
/* 测试此容器 */
int main(void)
{
List *list = create();
int i;
for(i = 1; i < 10; ++i)
{
put_integer( list, i, i*i ); //测试 put_integer
}
for(i = 1; i < 10; ++i)
{
print_list( list, i ); // 测试 print_list
printf("\n");
}
put_integer(list, 9, 113);
put_char( list, 21, 'a' ); // 测试 put_char
print_list(list, 21);
printf("\n");
put_string(list, 122, "What is it ?");// 测试 put_string
print_list(list, 122);
printf("\n");
put_binary(list, 15, "100010B", 6); // 测试 put_binary
print_list(list, 15);
printf("\n");
printf("len=%d\n", getlistNum(list) );// 测试 getlistNum
if( search_node(list, 15) ) printf("uid 15 存在\n" );
else printf("uid 15 不存在\n");
delete_list(list, 15); // 测试 delete_list
if( search_node(list, 15) ) printf("uid 15 存在\n" );
else printf("uid 15 不存在\n");
printf("\n");
delete_all_nodes(list);
system("pause");
return 0;
}
问题:存储空间浪费,存储char时字符数组的空间被大量浪费,对于我这个写单片机程序过来的人来说无法忍受。去改进还需要技巧,25号搞了后就放在这了。
/*数据结构起步*/
int put_char(List *list, unsigned int uid, char c); int put_string(List *list, unsigned int uid, char *str); int put_integer(List *list, unsigned int uid, int num); int put_binary(List *list, unsigned int uid, unsigned char* data, unsigned int data_len);
能遍历容器内数据节点,根据uid删除节点,打印节点。
unsigned int getNodeNum(List *list); int delete_node(List *list, unsigned int uid); int print_node(List *list, unsigned int uid); void delete_all_nodes(List *list);
我的解决方案:使用单链表,结构体里定义各数据类型,用一个标志位来标记数据类型,可以实现每个节点都能具有任意数据类型。
/**
******************************************************************************
* @file list.h
* @author summer
* @version V1.0
* @date 2015-05-25
* @brief C语言实现一个泛型容器
* 函数声明,功能注释在.c文件中。 ****************************************************************************** * @attention * IDE: Visual Studio 2010 * ****************************************************************************** */
#ifndef _LIST_H #define _LIST_H #define IS_INT 1 #define IS_CHAR 2 #define IS_STR 3 #define IS_BIN 4 #define FALSE 0 #define TRUE 1 typedef struct LIST { struct LIST *link; unsigned int uid; int int_value; char char_value; unsigned int mark; // mark来标记类型 IS_INT 1, IS_CHAR 2, IS_STR 3, IS_BIN 4 char str[100]; }List; List *create(); int search_node(List *list, unsigned int uid ); int put_char(List *list, unsigned int uid, char c); int put_string(List *list, unsigned int uid, const char *str); int put_integer(List *list, unsigned int uid, int num); int put_binary(List *list, unsigned int uid, const char* data, unsigned int data_len); int print_list(List *list, unsigned int uid); unsigned int getlistNum(List *list); int delete_list(List *list, unsigned int uid); void delete_all_nodes(List *list); #endif
/**
******************************************************************************
* @file list.c
* @author summer
* @version V1.0
* @date 2015-05-25
* @brief C语言实现一个泛型容器
* 具体实现 ****************************************************************************** * @attention * IDE: Visual Studio 2010 * ****************************************************************************** */ #include<stdlib.h> #include<stdio.h> #include<string.h> #include<assert.h> #include"list.h" /** *创建链表 */ List *create() { List *_list = (List *)malloc(sizeof(List)); // 分配一个不存放有效数据的头结点 List *_tail = _list; // 链表的最后一个节点 _tail->link = NULL; // 最后一个节点的指针置为空 int i; for(i = 0; i < 2; i++) { List *pNew = (List *)malloc( sizeof(List) );// 为节点分配空间 pNew->int_value = i; // 数据赋给节点的成员 pNew->mark = IS_INT; // 标记数据类型 _tail->link = pNew; // 将最后一个节点的指针指向新节点 pNew->link = NULL; // 将新节点中的指针置为空 _tail = pNew; // 将新节点赋给最后的一个节点 } return _list; } /** *遍历容器内有多少个数据节点 */ unsigned int getlistNum(List *list) { assert( list != NULL); unsigned int listNum=0; for(List *node = list->link; node != NULL ; node = node->link) { ++listNum; } return listNum; } /** * 根据标志码 uid 搜索节点 * 返回值:存在 TRUE * 不存在 FALSE */ int search_node(List *list, unsigned int uid ) { assert( list != NULL); List *node = list->link; while(node && node->uid != uid ) { node = node->link; } return ( node ) ? TRUE : FALSE; } /** *功能: 插入新节点到单链表 *参数: 指向链表第一个节点的指针, 节点唯一标识码 *返回值: 成功 返回指向新节点的指针 * 失败 返回 NULL */ List *insert(List *list, unsigned int new_uid ) { if ( NULL == list ) // 判断 list是否为空 { return NULL; } List *current = list; // 当前 if( search_node( list, new_uid ) == TRUE) {// uid 唯一性检测 printf("The id already exists!\n"); return NULL; } List *pNew = (List*)malloc( sizeof(List) ); if(pNew == NULL) { printf("插入失败\n"); } pNew->uid = new_uid; // 把输入的数据赋给要插入的节点 List *pNext = current->link;// 下一个节点的地址 current->link = pNew; // 把要插入的节点的地址,给上个节点的指针域 pNew->link = pNext; // 把插入节点的下一个节点的地址,给插入节点的指针域 return pNew; } /** *插入 char */ int put_char(List *list, unsigned int uid, char c) { List *next = insert(list, uid ); if(next == NULL) { return FALSE; } next->char_value = c; next->mark = IS_CHAR; printf("插入 char 成功\n"); return TRUE; } /** *插入int */ int put_integer(List *list, unsigned int uid, int num) { List *next = insert(list, uid ); if(next == NULL) { return FALSE; } next->int_value = num; next->mark = IS_INT; printf("插入int 成功\n"); return TRUE; } /** *插入字符串 */ int put_string(List *list, unsigned int uid, const char *new_str) { //#define STRING List *next = insert(list, uid ); if(next == NULL) { return FALSE; } strcpy(next->str, new_str ); next->mark = IS_STR; printf("插入 string 成功\n"); return TRUE; } /** *插入二进制 */ int put_binary(List *list, unsigned int uid, const char* data, unsigned int data_len) { //#define BINARY List *next = insert(list, uid ); if(next == NULL) { return FALSE; } strcpy(next->str, data ); next->mark = IS_STR; printf("插入 binary 成功\n"); return TRUE; } /** *打印节点 */ int print_list(List *list, unsigned int uid) { List *_list = list; if( _list->link == NULL) { printf("Link is empty!\n"); return FALSE; } while( _list->link != NULL) { if(_list->uid == uid ) { switch (_list->mark) { case IS_CHAR: printf("%c", _list->char_value ); break; case IS_INT: printf("%d", _list->int_value ); break; case IS_BIN: case IS_STR: printf("%s", _list->str ); break; default: printf("What happened?\n"); break; } return TRUE; }//if _list = _list->link; }//while printf("Not found!\n"); return FALSE; } /** *根据uid删除节点 */ int delete_list(List *list, unsigned int uid) { List *re_list, *_list = list;; if(list == NULL) { printf("找不到节点!\n"); return FALSE; } while( (_list->uid != uid) && (_list->link != NULL) ) { re_list = _list; _list = _list->link; } return ( _list->uid != uid) ? (printf("链表不存在此节点!\n"), FALSE) : (re_list->link = _list->link, free(_list), printf("删除节点成功!\n"), TRUE); // 问号表达式省了不少长度 } void delete_all_nodes(List *list) { List *_list = list; if (list == NULL) // 入口检测 return; while(_list->link != NULL) // 删除链表非首结点元素 { List *current = _list->link; _list->link = _list->link->link; free(current); } free(_list); // 删除链表首结点 4000 元素 list = NULL; printf("删除所有节点成功\n"); }
测试程序
#include <stdio.h>
#include <stdlib.h>
#include"list.h"
/* 测试此容器 */
int main(void)
{
List *list = create();
int i;
for(i = 1; i < 10; ++i)
{
put_integer( list, i, i*i ); //测试 put_integer
}
for(i = 1; i < 10; ++i)
{
print_list( list, i ); // 测试 print_list
printf("\n");
}
put_integer(list, 9, 113);
put_char( list, 21, 'a' ); // 测试 put_char
print_list(list, 21);
printf("\n");
put_string(list, 122, "What is it ?");// 测试 put_string
print_list(list, 122);
printf("\n");
put_binary(list, 15, "100010B", 6); // 测试 put_binary
print_list(list, 15);
printf("\n");
printf("len=%d\n", getlistNum(list) );// 测试 getlistNum
if( search_node(list, 15) ) printf("uid 15 存在\n" );
else printf("uid 15 不存在\n");
delete_list(list, 15); // 测试 delete_list
if( search_node(list, 15) ) printf("uid 15 存在\n" );
else printf("uid 15 不存在\n");
printf("\n");
delete_all_nodes(list);
system("pause");
return 0;
}
问题:存储空间浪费,存储char时字符数组的空间被大量浪费,对于我这个写单片机程序过来的人来说无法忍受。去改进还需要技巧,25号搞了后就放在这了。
/*数据结构起步*/
相关文章推荐
- [C/C++]反转链表
- Lua和C语言的交互详解
- 关于C语言中参数的传值问题
- 深入C++中API的问题详解
- 基于C语言string函数的详解
- C语言内存对齐实例详解
- c语言实现的带通配符匹配算法
- C语言实现顺序表基本操作汇总
- 探讨C语言的那些小秘密之断言
- 深入探讨C语言中局部变量与全局变量在内存中的存放位置
- C语言泛型编程实例教程
- C语言中使用lex统计文本文件字符数
- 基于C语言fflush()函数的使用详解
- C语言单链队列的表示与实现实例详解
- 关于C语言除0引发的思考
- 深入分析C中不安全的sprintf与strcpy
- Lua教程(四):在Lua中调用C语言、C++的函数
- C语言求幂计算的高效解法
- C语言实现输入一颗二元查找树并将该树转换为它的镜像
- 12个关于C语言的有趣问答