处理任意类型链表模板

头文件:linkList.h

#ifndef   LINKLIST
#define _CRT_SECURE_NO_WARNINGS
#define   LINKLIST
#define   DEBUG
#define   TEST
#include <stdio.h>
#include <string.h>
#include <stdlib.h>//节点
typedef struct  LINKNODE
{void* data;struct  LINKNODE*next;
}linkNode;//链表
typedef struct LINKLIST
{linkNode* head;int  size;
}liskList;//初始化链表
liskList* initLinkList();//在指定位置新增数据
void insertLinkList(liskList *list,int pos,void *data);//定义输出节点指针类型
typedef  void (*PRINTNODE)(void*);//输出链表
void printLinkList(liskList* list, PRINTNODE printNode);//删除数据【按位置】
void removeLinkList(liskList* list, int pos);//获取链表节点数
int sizeLinkList(liskList* list);//获取首节点
void* firstLinkList(liskList* list);//查找节点[按数据地址]
int  findLinkList(liskList* list,void *data);//释放
void freeLinkList(liskList* list);//定义输出节点指针类型
//typedef  void (*COMPARY)(void* sour,void *dest);//查找节点【按数据内容】
//int  findLinkList(liskList* list, void *data,COMPARY com);#endif

源文件:linkList.c

#include "linkList.h"
//初始化链表
liskList* initLinkList()
{
#ifdef DEBUGprintf("function:initLinkList\n");
#endif // DEBUGliskList* list = malloc(sizeof(liskList));if (list != NULL){list->size = 0;//头节点--[不保存数据]list->head = (linkNode*)malloc(sizeof(linkNode));if (list->head != NULL){list->head->data = NULL;list->head->next = NULL;return list;}return NULL;}return NULL;
}//在指定位置新增数据
void insertLinkList(liskList* list, int pos, void* data)
{
#ifdef DEBUGprintf("function:insertLinkList\n");
#endif // DEBUGint i;if (list == NULL){printf("链表未初始化\n");return;}if (data == NULL){printf("数据未初始化\n");return;}if (pos<0 || pos>list->size){pos = list->size;}//创建新节点linkNode* newNode = (linkNode*)malloc(sizeof(linkNode));if (newNode != NULL){newNode->data = data;newNode->next = NULL;//辅助指针linkNode* pCurrent = NULL;//从头结点开始确定位置pCurrent = list->head;//辅助指针找到位置后准备插入数据for (i=0;i<pos;i++){pCurrent = pCurrent->next;}//新节点插入newNode->next = pCurrent->next;pCurrent->next = newNode;list->size++;}
}//输出链表
void printLinkList(liskList* list, PRINTNODE printNode)
{
#ifdef DEBUGprintf("function:printLinkList\n");
#endif // DEBUGint i=0;if (list == NULL){printf("链表未初始化");return;}linkNode* pCurrent = NULL;pCurrent = list->head->next;while (pCurrent!=NULL){printf("[%d] ",i); printNode(pCurrent->data);i++;pCurrent = pCurrent->next;}
}//删除数据【按位置】
void removeLinkList(liskList* list, int pos)
{
#ifdef DEBUGprintf("function:removeLinkList\n");
#endif // DEBUGint i;if (list == NULL){printf("链表未初始化\n");return;}if (pos<0 || pos>list->size){printf("位置无效\n");return;}//查找删除节点的前一个节点linkNode* pCurrent = list->head;for (i = 0; i < pos; i++){pCurrent = pCurrent->next;}//pCurrent->next=   pCurrent->next->next;  //此写法可以删除节点,但是不能free【释放要删除的节点】//暂存要删除的节点linkNode* pDel = pCurrent->next;pCurrent ->next =pDel->next;free(pDel);list->size--;
}//获取链表节点数
int sizeLinkList(liskList* list)
{
#ifdef DEBUGprintf("function:sizeLinkList\n");
#endif // DEBUGif (list == NULL){printf("链表未初始化\n");return -1;}return list->size;
}//获取首节点数据
void* firstLinkList(liskList* list)
{
#ifdef DEBUGprintf("function:firstLinkList\n");
#endif // DEBUGif (list == NULL){printf("链表未初始化\n");return NULL;}if (list->size == 0){printf("暂无节点\n");return NULL;}return list->head->next->data;
}//查找节点
int  findLinkList(liskList* list, void* data)
{
#ifdef DEBUGprintf("function:findLinkList\n");
#endif // DEBUGint i;if (list == NULL){printf("链表未初始化\n");return -1;}if (data==NULL){printf("不能查找NULL数据\n");return -2;}if (list->size == 0){printf("暂无数据\n");return -3;}linkNode* pCurrent = list->head->next;i = 0;int leap = -10;while (pCurrent != NULL){if ( pCurrent->data == data){return i;}pCurrent = pCurrent->next;i++;}return leap;
}//释放
void freeLinkList(liskList* list)
{
#ifdef DEBUGprintf("function:freeLinkList\n");
#endif // DEBUGint i;if (list == NULL){printf("链表未初始化\n");return ;}linkNode* pFree = list->head;linkNode* pCurrent=NULL;while (pFree != NULL){pCurrent= pFree->next;#ifdef DEBUGprintf("释放 %p\n", pFree);
#endif // DEBUGfree(pFree);pFree = pCurrent;}#ifdef DEBUGprintf("释放 %p\n", list);
#endif // DEBUGfree(list);
}

源文件:main.c

#include "linkList.h"//自定义数据
typedef struct Person
{char name[64];int age;int score;
}person;// 自定义数据的输出
void printNode(void *data)
{person* p = (person*)data;printf("%s %d %d\n",p->name,p->age,p->score);
}int main()
{liskList* list = initLinkList();#ifdef DEBUGprintf("%p\n", list);printf("%p\n", list->head);printf("%d\n", list->size);
#endif // DEBUGperson p1 = { "aaaaa",23,98 };person p2 = { "ccccc",24,88 };person p3 = { "ddddd",19,78 };person p4 = { "ggggg",29,93 };person p5 = { "jjjjjjj",33,88 };person p6 = { "oooooo",20,91 };person p7 = { "xxxxxxxx",17,88 };person p9,p10;//向指定位置新增数据insertLinkList(list, 0, (void *)&p1);insertLinkList(list, 0, (void*)&p2);insertLinkList(list, 0, (void*)&p3);insertLinkList(list, 0, (void*)&p4);insertLinkList(list, 0, (void*)&p5);//输出//printLinkList(list, printNode);insertLinkList(list, 8, (void*)&p6);//puts("-----------------------------");//输出//printLinkList(list, printNode);insertLinkList(list, 2, (void*)&p7);//puts("++++++++++++++++");//输出printLinkList(list, printNode);printf("节点数:%d\n", sizeLinkList(list));printNode(firstLinkList(list));//removeLinkList(list, 99);removeLinkList(list, 0);//removeLinkList(list, 6);//removeLinkList(list, 3);puts("++++++++++++++++");//输出printLinkList(list, printNode);printNode(firstLinkList(list));printf("节点数:%d\n",sizeLinkList(list));printf("查找:%d\n",findLinkList(list,(void *) &p10));freeLinkList(list);return 0;
}

处理任意类型链表模板相关推荐

  1. 数据结构与算法:单链表(利用万能指针实现对任意类型数据进行操作)

    前言 C语言的指针真的很强大,万能指针更强大,可以指向任意类型的数据.在上篇博客 数据结构与算法:单链表(超详细实现)中用C语言实现了单链表的相关算法,不过却有局限性 只能针对某一种数据类型还是不够强 ...

  2. 比大小,人类智慧天花板,任意类型,任意个数。内容包含函数模板的创建,类的创建,动态内存的分配与释放,函数调用指针的用法。牵扯多个知识点。

    比大小,看这一篇就足够,大家好,我是姜姜一名热爱C++编程的大学生,接下来我将通过代码演示如何利用C++实现任意类型,任意个数的比大小,并且找出最大的数. 由于本人比较懒,所有没写注释还请各位读者多多 ...

  3. 数据结构与算法:动态数组(利用万能指针实现任意类型数组操作)

    原理介绍 我们利用万能指针来实现动态数组,数组元素类型可以是任意类型,因为我们只维护用户提供的数据的地址,所以可以用万能指针来接受,这样就实现了类似C++中的模板功能了. 先说说动态数组和静态数组.静 ...

  4. C++随机产生任意类型某个区间范围的随机数

    srand和rand()配合使用产生伪随机数序列.rand函数在产生随机数前,需要系统提供的生成伪随机数序列的种子,rand根据这个种子的值产生一系列随机数.如果系统提供的种子没有变化,每次调用ran ...

  5. 4-C++ 中string类、bool类型、模板、array数组、vector向量的基础知识

    目录 继续C++ ------3 ++操作符的友元函数重载 ++操作符的成员函数重载 赋值运算符重载 类型转换运算符 运算符重载注意事项 string类 bool类型的练习 模板 1.函数模板 2.类 ...

  6. 单链表模板类c++实现

    1.题目描述 实现课本中的带附加头结点的单链表模板类,完成如下功能: 定义链表节点的结构体类型,构造函数和析构函数,单链表的输入输出 引用型操作:getData,Locate ,Search,Leng ...

  7. JSON学习笔记-混合任意类型的堆栈

    问题提出 我们在解析JSON时,需要多次调用堆栈来解析对象,这时主要产生了两个问题: 1)多次调用需要大量的申请一块类似的内存空间,然后又释放掉,耗费时间.如果当前系统中有大量的内存碎片,并且我们申请 ...

  8. c++模板 --- 类模板、自定义类型当做模板参数

    生成一个类模板 类中用到了未知类型叫做类模板 用 template 修饰的类,这个类就是一个模板类 多用在数据结构中,忽略类型的问题 只要被 template 修饰,就是一个模板类,有没有用未知类型都 ...

  9. 在SQL Server中保存和输出任意类型的文件

    我们可以把任意类型的文件保存到SQL Server中,在进行例子之前,先建立测试用表格,TestFile.sql: if exists (select * from dbo.sysobjects wh ...

  10. runtime 任意类型 model 数据库方便存储

    //这里边直接上代码 之后我在慢慢地讲解  之后我的QQ:378254160 我有DEMO 方便你们的使用联系我备注 runtime+数据库+任意model类型  当然有时候也是有局限的 //Data ...

最新文章

  1. CentOS7 安装chrome浏览器和ChromeDriver 及 python脚本调用chrome浏览器
  2. IT公司笔试题总结(三)
  3. Docker最全教程之使用TeamCity来完成内部CI、CD流程(十七)
  4. 对于个人(注册表)与团队(团队表)(两张表没有关联)的展示与可空判断
  5. Java—static关键字
  6. [转]如何处理机器学习中的不平衡类别
  7. 如何解除FSO上传程序小于200k限制?
  8. Java的getperiod_Java中的Period getYears()方法
  9. 宁夏计算机科学与技术产业发展新趋势,2021年CCF数据库发展战略研讨会在宁夏银川顺利召开...
  10. iPhone开发学习笔记005——使用XIB自定义一个UIView,然后将这个view添加到controller的view...
  11. python画散点图、折线图
  12. linux的pascal语言,pascal语言视频教程 Linux GCC常用命令详解
  13. web项目开发上传功能
  14. 如何查看本机flash版本
  15. 手把手带二大爷用EasyDL实现戴口罩检测APP
  16. Java 实现打印超市小票
  17. ZPL 打印条码、二维码及小票(中文/汉字),生成条码、二维码图片【Asp.Net】-含示例代码
  18. 计算机软件可以授予专利权吗,软件产品能申请专利吗?
  19. BBS 与 BLog(博客)的区别到底是什么?[转载]
  20. python解复杂方程_Python 解方程的三种方法

热门文章

  1. 软件腐化的七个特征之复杂性、重复性、晦涩性(设计模式原则的反面) (《敏捷软件开发》读书总结第三篇)
  2. 苹果cms怎么上传本地视频资源
  3. ARVR游戏开发中常用到的人物模型合集
  4. php表格整体怎么移动,超级表格新版移动端操作指南
  5. 矸石称重自动化系统有什么特点
  6. matlab中ode23s使用方法,MATLAB中ode23函数,龙格库塔函数
  7. 架构师说低代码:走出半生,归来仍是“毒瘤”!
  8. 互联网最值得加入的 173 家国企汇总!!
  9. bootstrap btn按钮颜色
  10. 如何在html中加入动图,如何在PS图像中插入动图(gif)?