数据结构 传统链表实现与Linux内核链表
头文件:
#pragma once#include<stdlib.h>//链表结点 struct LinkNode{void *data;struct LinkNode *next; };//链表 struct _Linklist{struct LinkNode header;int size; //链表结点的数目 };typedef void *LinkList;#ifdef __cplusplus extern "C" { #endif//初始化链表 LinkList Init_LinkList();//指定位置插入int InsertByPos_LinkList(LinkList list, int pos, void *data);//头插int PushFront_LinkList(LinkList list, void *data);//尾插int PushBack_LinkList(LinkList list, void *data);//在指定值的前面插入int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*,void*));//指定位置删除int RemoveByPos_LinkList(LinkList list, int pos);//根据值删除int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *));//头删void PopFront_LinkList(LinkList list);//尾删void PopBack_LinkList(LinkList list);//遍历void Foreach_LinkList(LinkList list, void(*foreach)(void *));//销毁void Destroy_LinkList(LinkList list);#ifdef __cplusplus } #endif
头文件实现:
#include"LinkList.h"//初始化链表 LinkList Init_LinkList(){struct _Linklist *list = malloc(sizeof(struct _Linklist));if (NULL == list){return NULL;}list->header.data = NULL;list->header.next = NULL;list->size = 0;return list; } //指定位置插入 0代表插入到第一个位置 int InsertByPos_LinkList(LinkList list, int pos, void *data){if (NULL == list){return -1;}if (NULL == data){return -2;}struct _Linklist *llist = (struct _Linklist *)list;if (pos < 0 || pos > llist->size){pos = llist->size;}//辅助指针变量struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos;i ++){pCurrent = pCurrent->next;}//创建新结点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = data;newnode->next = NULL;//新结点入链表newnode->next = pCurrent->next;pCurrent->next = newnode;//sizellist->size++;return 0; } //头插 int PushFront_LinkList(LinkList list, void *data){return InsertByPos_LinkList(list, 0, data); } //尾插 int PushBack_LinkList(LinkList list, void *data){if (NULL == list){return -1;}struct _Linklist *llist = (struct _Linklist *)list;return InsertByPos_LinkList(list,llist->size - 1,data); } //在指定值的前面插入 int InsertByVal_LinkList(LinkList list, void *oldval, void *newval, int(*isequal)(void*, void*)){if(NULL ==list){return -1;}if (NULL == oldval){return -2;}if (NULL == newval){return -3;}if (NULL == isequal){return -4;}struct _Linklist *llist = (struct _Linklist *)list;//辅助指针变量struct LinkNode *pPrev = &(llist->header);struct LinkNode *pCurrent = pPrev->next;while (pCurrent != NULL){if (isequal(pCurrent->data, oldval)){//创建新结点struct LinkNode *newnode = malloc(sizeof(struct LinkNode));newnode->data = newval;newnode->next = NULL;//新结点入链表pPrev->next = newnode;newnode->next = pCurrent;llist->size++;break;}pPrev = pCurrent;pCurrent = pCurrent->next;}return 0; } //指定位置删除 int RemoveByPos_LinkList(LinkList list, int pos){if (NULL == list){return -1;}struct _Linklist *llist = (struct _Linklist *)list;if (llist->size == 0){return 0;}if (pos < 0 || pos > llist->size - 1){return 0;}//辅助指针变量//找到待删除结点的前一个结点struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos;i ++){pCurrent = pCurrent->next;}//缓存下待删除结点struct LinkNode *pDel = pCurrent->next;//重新建立待删除结点的前驱后继结点关系pCurrent->next = pDel->next;//删除结点内存free(pDel);pDel = NULL;llist->size--;return 0; } //根据值删除 int RemoveByVal_LinkList(LinkList list, void *data, int(*compare)(void *, void *)){if (NULL == list){return -1;}if (NULL == data){return -2;}if (NULL == compare){return -3;}struct _Linklist *llist = (struct _Linklist *)list;//辅助指针变量struct LinkNode *pPrev = &(llist->header);struct LinkNode *pCurrent = pPrev->next;while (pCurrent != NULL){if (compare(pCurrent->data, data)){pPrev->next = pCurrent->next;free(pCurrent);llist->size--;break;}pPrev = pCurrent;pCurrent = pPrev->next;}return 0; } //头删 void PopFront_LinkList(LinkList list){RemoveByPos_LinkList(list, 0); } //尾删 void PopBack_LinkList(LinkList list){if (NULL == list){return;}struct _Linklist *llist = (struct _Linklist *)list;RemoveByPos_LinkList(list, llist->size - 1); } //遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *)){if (NULL == list){return;}if (NULL == foreach){return;}struct _Linklist *llist = (struct _Linklist *)list;//辅助指针变量struct LinkNode *pCurrent = llist->header.next;while (pCurrent != NULL){foreach(pCurrent->data);pCurrent = pCurrent->next;}} //销毁 void Destroy_LinkList(LinkList list){if (NULL == list){return;}struct _Linklist *llist = (struct _Linklist *)list;//辅助指针变量struct LinkNode *pCurrent = llist->header.next;while (pCurrent != NULL){//缓存下一个结点struct LinkNode *pNext = pCurrent->next;//释放当前结点内存free(pCurrent);//指针移动到下一个结点的位置pCurrent = pNext;}free(llist);llist = NULL; }
测试代码:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include"LinkList.h"struct Person{char name[64];int age; };void MyPrint(void *data){struct Person *person = (struct Person *)data;printf("Name:%s Age:%d\n", person->name,person->age); }int MyCompare(void *d1,void *d2){struct Person *p1 = (struct Person *)d1;struct Person *p2 = (struct Person *)d2;return strcmp(p1->name, p2->name) == 0 && p1->age == p2->age; }void test(){//创建测试数据struct Person p1 = { "aaa", 10 };struct Person p2 = { "bbb", 20 };struct Person p3 = { "ccc", 30 };struct Person p4 = { "ddd", 40 };struct Person p5 = { "eee", 50 };struct Person p6 = { "fff", 60 };struct Person p7 = { "ggg", 70 };//初始化链表LinkList list = Init_LinkList();//将数据插入链表InsertByPos_LinkList(list, 0, &p1);InsertByPos_LinkList(list, 0, &p2);InsertByPos_LinkList(list, 0, &p3); InsertByPos_LinkList(list, 1, &p4);InsertByPos_LinkList(list, 0, &p5);InsertByPos_LinkList(list, 0, &p6);//遍历 6 5 3 4 2 1 Foreach_LinkList(list, MyPrint);printf("-------------------\n");printf("在name为ccc,age为30的数据前面插入:\n");InsertByVal_LinkList(list, &p3, &p7, MyCompare);Foreach_LinkList(list, MyPrint);printf("删除位置4的数据:\n");RemoveByPos_LinkList(list,4);Foreach_LinkList(list, MyPrint);printf("删除name为ggg age为70的数据:\n");RemoveByVal_LinkList(list, &p7, MyCompare);Foreach_LinkList(list, MyPrint);//销毁链表 Destroy_LinkList(list); }int main(){test();system("pause");return EXIT_SUCCESS; }
链表版本二:通过修改指针的指向的区域的大小,实现数据链接,给用户使用
头文件:
#pragma once#include<stdlib.h>//链表小节点//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型 struct LinkNode{struct LinkNode *next; };//链表结构体 struct LList{struct LinkNode header;int size; };typedef void *LinkList;//初始化 LinkList Init_LinkList();//指定位置插入 void Insert_LinkList(LinkList list, int pos, struct LinkNode *data); //位置删除 void RemoveByPos_LinkList(LinkList list, int pos); //遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *));//销毁 void Destroy_LinkList(LinkList list);
头文件实现:
#include"LinkList.h"//初始化 LinkList Init_LinkList(){struct LList *list = malloc(sizeof(struct LList));if (NULL == list){return NULL;}list->header.next = NULL;list->size = 0;return list; } //指定位置插入 void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){if (NULL == list){return;}if (NULL == data){return;}struct LList *llist = (struct LList *)list;if (pos < 0 || pos >llist->size){pos = llist->size;}//查找pos位置前一个位置的节点struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos;i ++){pCurrent = pCurrent->next;}//将新节点插入到链表data->next = pCurrent->next;pCurrent->next = data;llist->size++; }//位置删除 void RemoveByPos_LinkList(LinkList list, int pos){if (NULL ==list){return;}struct LList *llist = (struct LList *)list;if (llist->size == 0){return;}if (pos < 0 || pos > llist->size - 1){return;}//找到pos位置的前一个节点struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos; i ++){pCurrent = pCurrent->next;}//缓存下待删除节点struct LinkNode *pDel = pCurrent->next;//重新建立待删除的节点前驱后继节点关系pCurrent->next = pDel->next;llist->size--; }//遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *)){if (NULL == list){return;}struct LList *llist = (struct LList *)list;//辅助指针变量struct LinkNode *pCurrent = llist->header.next;while (pCurrent != NULL){foreach(pCurrent);pCurrent = pCurrent->next;} }
测试函数:
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include"LinkList.h"struct Person{struct LinkNode node;char name[64];int age; };void MyPrint(void *data){struct Person *person = (struct Person *)data;printf("Name:%s Age:%d\n",person->name,person->age); }void ChanageValue(void *data){struct Person *person = (struct Person *)data;person->age += 100; }//#define ISSTACKvoid test(){//创建测试数据 #ifdef ISSTACKstruct Person p1 = { NULL , "aaa", 10 };struct Person p2 = { NULL , "bbb", 20 };struct Person p3 = { NULL , "ccc", 30 };struct Person p4 = { NULL , "ddd", 40 };struct Person p5 = { NULL , "eee", 50 }; #elsestruct Person *p1 = malloc(sizeof(struct Person));struct Person *p2 = malloc(sizeof(struct Person));struct Person *p3 = malloc(sizeof(struct Person));struct Person *p4 = malloc(sizeof(struct Person));struct Person *p5 = malloc(sizeof(struct Person));strcpy(p1->name, "aaa");strcpy(p2->name, "bbb");strcpy(p3->name, "ccc");strcpy(p4->name, "ddd");strcpy(p5->name, "eee");p1->age = 10;p2->age = 20;p3->age = 30;p4->age = 40;p5->age = 50;#endif//初始化链表LinkList list = Init_LinkList(); #ifdef ISSTACK//数据插入到链表Insert_LinkList(list, 0, (struct LinkNode *)&p1);Insert_LinkList(list, 0, (struct LinkNode *)&p2);Insert_LinkList(list, 0, (struct LinkNode *)&p3);Insert_LinkList(list, 0, (struct LinkNode *)&p4);Insert_LinkList(list, 0, (struct LinkNode *)&p5); #elseInsert_LinkList(list, 0, (struct LinkNode *)p1);Insert_LinkList(list, 0, (struct LinkNode *)p2);Insert_LinkList(list, 0, (struct LinkNode *)p3);Insert_LinkList(list, 0, (struct LinkNode *)p4);Insert_LinkList(list, 0, (struct LinkNode *)p5); #endif//遍历 Foreach_LinkList(list, MyPrint);//删除2号位置printf("------------------\n");RemoveByPos_LinkList(list, 3);Foreach_LinkList(list, MyPrint);//遍历修改数据printf("---------------------\n");//Foreach_LinkList(list, ChanageValue);//Foreach_LinkList(list, MyPrint);//销毁链表 Destroy_LinkList(list);free(p1);free(p2);free(p3);free(p4);free(p5);}int main(){test();system("pause");return EXIT_SUCCESS; }
以链表为底层容器实现栈
头文件:
容器头文件:
#pragma once
#include<stdlib.h>
//链表小节点
//目的 : 第一,让用户数据包含 第二,我需要把用户指针类型转换成struct LinkNode*类型
struct LinkNode{
struct LinkNode *next;
};
//链表结构体
struct LList{
struct LinkNode header;
int size;
};
typedef void *LinkList;
//初始化
LinkList Init_LinkList();
//指定位置插入
void Insert_LinkList(LinkList list, int pos, struct LinkNode *data);
//位置删除
void RemoveByPos_LinkList(LinkList list, int pos);
//遍历
void Foreach_LinkList(LinkList list, void(*foreach)(void *));
//根据位置获得值
void *Get_LinkList(LinkList list,int pos);
int Size_LinkList(LinkList list);
//销毁
void Destroy_LinkList(LinkList list);
栈头文件:
#pragma once#include"LinkList.h"struct StackNode{struct LinkNode node; };typedef void *LinkStack;//初始化 LinkStack Init_LinkStack(); //入栈 void Push_LinkStack(LinkStack stack, void *data); //出栈 void Pop_LinkStack(LinkStack stack); //获得栈顶元素 void *Top_LinkStack(LinkStack stack); //大小 int Size_LinkStack(LinkStack stack); //销毁栈 void Destroy_LinkStack(LinkStack stack);
头文件实现:
容器头文件实现:
#include"LinkList.h"//初始化 LinkList Init_LinkList(){struct LList *list = malloc(sizeof(struct LList));if (NULL == list){return NULL;}list->header.next = NULL;list->size = 0;return list; } //指定位置插入 void Insert_LinkList(LinkList list, int pos, struct LinkNode *data){if (NULL == list){return;}if (NULL == data){return;}struct LList *llist = (struct LList *)list;if (pos < 0 || pos >llist->size){pos = llist->size;}//查找pos位置前一个位置的节点struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos;i ++){pCurrent = pCurrent->next;}//将新节点插入到链表data->next = pCurrent->next;pCurrent->next = data;llist->size++; }//位置删除 void RemoveByPos_LinkList(LinkList list, int pos){if (NULL ==list){return;}struct LList *llist = (struct LList *)list;if (llist->size == 0){return;}if (pos < 0 || pos > llist->size - 1){return;}//找到pos位置的前一个节点struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos; i ++){pCurrent = pCurrent->next;}//缓存下待删除节点struct LinkNode *pDel = pCurrent->next;//重新建立待删除的节点前驱后继节点关系pCurrent->next = pDel->next;llist->size--; }//根据位置获得值 void *Get_LinkList(LinkList list, int pos){if (NULL == list){return NULL;}struct LList *llist = (struct LList *)list;if (pos < 0 || pos > llist->size - 1){return NULL;}//辅助指针变量struct LinkNode *pCurrent = &(llist->header);for (int i = 0; i < pos; i++){pCurrent = pCurrent->next;}return pCurrent->next; }int Size_LinkList(LinkList list){if (NULL == list){return -1;}struct LList *llist = (struct LList *)list;return llist->size; }//遍历 void Foreach_LinkList(LinkList list, void(*foreach)(void *)){if (NULL == list){return;}struct LList *llist = (struct LList *)list;//辅助指针变量struct LinkNode *pCurrent = llist->header.next;while (pCurrent != NULL){foreach(pCurrent);pCurrent = pCurrent->next;} }//销毁 void Destroy_LinkList(LinkList list){if (NULL == list){return;}free(list);list = NULL; }
栈头文件实现:
#include"LinkStack.h"//初始化 LinkStack Init_LinkStack(){return Init_LinkList(); } //入栈 void Push_LinkStack(LinkStack stack, void *data){Insert_LinkList(stack, 0, data); } //出栈 void Pop_LinkStack(LinkStack stack){RemoveByPos_LinkList(stack, 0); } //获得栈顶元素 void *Top_LinkStack(LinkStack stack){return Get_LinkList(stack, 0); } //大小 int Size_LinkStack(LinkStack stack){return Size_LinkList(stack); } //销毁栈 void Destroy_LinkStack(LinkStack stack){Destroy_LinkList(stack); }
测试文件
#define _CRT_SECURE_NO_WARNINGS #include<stdio.h> #include<string.h> #include<stdlib.h> #include"LinkStack.h"struct Person{struct StackNode node;char name[64];int age; };void test(){//创建测试数据struct Person p1 = { NULL, "aaa", 10 };struct Person p2 = { NULL, "bbb", 20 };struct Person p3 = { NULL, "ccc", 30 };struct Person p4 = { NULL, "ddd", 40 };struct Person p5 = { NULL, "eee", 50 };//初始化栈LinkStack stack = Init_LinkStack();//数据入栈Push_LinkStack(stack , &p1);Push_LinkStack(stack, &p2);Push_LinkStack(stack, &p3);Push_LinkStack(stack, &p4);Push_LinkStack(stack, &p5);//输出栈中元素while (Size_LinkStack(stack) > 0){//获得栈顶元素struct Person *person = (struct Person*)Top_LinkStack(stack);//输出元素printf("Name:%s Age:%d\n",person->name,person->age);//弹出栈顶元素 Pop_LinkStack(stack);}printf("Size%d\n",Size_LinkStack(stack));//销毁栈 Destroy_LinkStack(stack); }int main(){test();system("pause");return EXIT_SUCCESS; }
转载于:https://www.cnblogs.com/w-x-me/p/6780998.html
数据结构 传统链表实现与Linux内核链表相关推荐
- linux内核链表使用例,linux内核链表的使用例子
linux内核链表的使用例子 #include #include #include #include #include #include MODULE_LICENSE("GPL") ...
- Linux内核链表交换节点,[笔记]Linux内核链表:结点的插入、删除以及链表的遍历...
Linux内核链表:结点的插入.删除以及链表的遍历 1. Linux内核链表的核心思想是:在用户自定义的结构A中声明list_head类型的成员p,这样每个结构类型为A的变量a中,都拥有同样的成员p, ...
- Linux内核链表访问链表头指针,linux内核——链表结构分析
http://blog.csdn.net/tigerjibo/article/details/8299584 简单整理(使用linux3.0内核) 这里首先学习的是内核中一种抽象定义的双向链表,为了提 ...
- linux内核链表分析
一.常用的链表和内核链表的区别 1.1 常规链表结构 通常链表数据结构至少应包含两个域:数据域和指针域,数据域用于存储数据,指针域用于建立与下一个节点的联系.按照指针域的组织以及各个节 ...
- Linux 内核 链表 的简单模拟(1)
第零章:扯扯淡 出一个有意思的题目:用一个宏定义FIND求一个结构体struct里某个变量相对struc的编移量,如 structstudent {int a; //FIND(struct stude ...
- 第六天2017/04/11(2:Linux内核链表Demo、顺序表、链表的开发与设计)
//结构体相关的高级话题#include "stdio.h" #include "stdlib.h" #include "string.h" ...
- linux内核链表以及list_entry--linux内核数据结构(一)
传统的链表实现 之前我们前面提到的链表都是在我们原数据结构的基础上增加指针域next(或者prev),从而使各个节点能否链接在一起, 比如如下的结构信息 typedef struct fox { un ...
- linux内核链表的使用
linux内核链表: 链表通常包括两个域:数据域和指针域. struct list_head{ struct list_head *next,*prev; }; include/linux/list. ...
- Linux内核链表深度分析【转】
本文转载自:http://blog.csdn.net/coding__madman/article/details/51325646 链表简介: 链表是一种常用的数据结构,它通过指针将一系列数据节点连 ...
最新文章
- Android--状态栏的图标和文字提醒/NotificationManager与Notification对象的应用
- ubuntu 设置开机启动与关闭开机启动(适用于部分linux系统)
- 1.9 实例:截取新闻标题
- MySQL中varchar所占字节大小是多少
- cloudwatch监控_Amazon CloudWatch:无服务器日志记录和监控基础
- c语言中的下标,c语言中数组的下标从什么入手下手?_后端开发
- mceliece加密算法c语言,一种安全轻量的McEliece公钥掩码加密方法技术
- Linux 14.04 CUDA theano安装
- 联想t168服务器安装系统,联想万全T168服务器技术亮点
- 通达OA 一个正式用户被提示软件试用过期的问题处理(图文)
- Android注册时总是出现验证码不正确问题的解决
- 相机标定—— 张正友标定法(2)
- YYC优雅草松鼠聚合直播系统·前端视频模块显示空白-解决办法-视频上传处理方法
- QtCreator一键重命名
- 关于计算机网络海明Hamming Code校验码, CRC及奇偶码校验
- YAML详解 是什么
- 人员离职it检查_公司软件开发人员离职信_检讨书
- MySQL - binlog 图文详解
- 源生的html属性js,使用源生JS自定义动画(支持多个属性)
- 校园二手交易商城系统小程序-JAVA【数据库设计、源码、开题报告】