传统的链表不能实现数据和链表的分离,一旦数据改变则链表就不能用了,就要重新开发。

如上说示:外层是Teacher,里面小的是node.

#ifndef _MYLINKLIST_H_
#define _MYLINKLIST_H_ typedef void LinkList;//链表上下文,任意类型 typedef struct _tag_LinkListNode
{
struct _tag_LinkListNode* next;//包含下一个节点的地址
}LinkListNode;//节点 LinkList* LinkList_Create(); void LinkList_Destroy(LinkList* list); void LinkList_Clear(LinkList* list); int LinkList_Length(LinkList* list); int LinkList_Insert(LinkList* list, LinkListNode* node, int pos); LinkListNode* LinkList_Get(LinkList* list, int pos); LinkListNode* LinkList_Delete(LinkList* list, int pos); #endif
#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.h" typedef struct _tag_LinkList//这个链表的上下文信息,类似于handle.这里面是链表的头结点和链表的长度。
{
LinkListNode header;
int length;
}TLinkList; LinkList* LinkList_Create() //O(1)
{
TLinkList *tmp = NULL; tmp = (TLinkList *)malloc(sizeof(TLinkList));
if (tmp == NULL)
{
printf("func LinkList_Create() err \n");
return NULL;
}
memset(tmp, , sizeof(TLinkList));
tmp->length = ;
tmp->header.next = NULL; //
return tmp;
} void LinkList_Destroy(LinkList* list) //O(1)
{
if (list == NULL)
{
return ;
}
free(list);//只把上下文信息释放。因为加进去的Teacher对象是局部的,main函数执行完后会自动释放,所以这里不用手动释放。
return ;
} void LinkList_Clear(LinkList* list) //O(1)
{
TLinkList *tList = NULL;
tList = (TLinkList *)list;
if (tList == NULL)
{
return ;
}
tList->header.next = NULL;
tList->length = ; return ;
} int LinkList_Length(LinkList* list) //O(1)
{
TLinkList *tList = NULL;
tList = (TLinkList *)list;
if (tList == NULL)
{
return -;
}
return tList->length;
} int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) //在pos位置插入节点,先连接后面的再连接前面的。
{
int i = ;
LinkListNode *current = NULL;
TLinkList *tList = NULL;
if (list==NULL || node==NULL || pos<)//node为新节点
{
return -;
}
tList = (TLinkList *)list; current = &(tList->header);//节点要取地址给指针
for (i=; i<pos; i++)//链表节点序号从0开始
{
current = current->next;//current为pos位置前面的节点
}
//先连接后面节点在连接前面节点
node->next = current->next; //前面的链表 连接 新结点
current->next = node; tList->length ++;
return ;
} LinkListNode* LinkList_Get(LinkList* list, int pos) //O(n)
{
int i = ;
LinkListNode *current = NULL;
TLinkList *tList = NULL; tList = (TLinkList *)list; if (list==NULL || pos<)
{
return NULL;
} current = &(tList->header); //赋值指针变量初始化
for (i=; i<pos; i++)
{
current = current->next;
}
return current->next;
} LinkListNode* LinkList_Delete(LinkList* list, int pos) //O(n)
{
int i = ;
LinkListNode *current = NULL;
LinkListNode *ret = NULL;
TLinkList *tList = NULL; tList = (TLinkList *)list;
if (list==NULL || pos<)
{
return NULL;
} current = &(tList->header);
for (i=; i<pos; i++)
{
current = current->next;
}
ret = current->next; //缓存要删除的结点 current->next = ret->next; tList->length --; return ret;
}
#define  _CRT_SECURE_NO_WARNINGS
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.h" /*
typedef struct _Node
{
struct _Node *next;
}Node; typedef struct _Teacher1
{
char name[32];
int age ;
Node node;
}Teacher1; typedef struct _Teacher2
{
Node node;
char name[32];
int age ; }Teacher2; Teacher2 t2;
*/ typedef struct _Teacher
{
LinkListNode node; //偏移量:从node元素找到Teacher的地址。写到上面则node的内存首地址和Teacher对象的内存首地址重叠了。
char name[];
int age ;
}Teacher; void main()
{
LinkList *list = NULL;
int i = ; Teacher t1, t2, t3, t4, t5, t6;//main函数结束这几个变量释放
t1.age = ;
t2.age = ;
t3.age = ;
t4.age = ;
t5.age = ;
t6.age = ; list = LinkList_Create(); //思考1: 业务节点 和 链表算法是如何分离
//思考2: 业务节点的生命周期 归谁管... //插入元素
LinkList_Insert(list, (LinkListNode *)&t1, );//t1地址和node地址是重叠的
LinkList_Insert(list, (LinkListNode *)&t2, );
LinkList_Insert(list, (LinkListNode *)&t3, );
LinkList_Insert(list, (LinkListNode *)&t4, );
LinkList_Insert(list, (LinkListNode *)&t5, );
LinkList_Insert(list, (LinkListNode *)&t6, ); //遍历链表
for (i=; i<LinkList_Length(list); i++)
{
Teacher *tmp = (Teacher *)LinkList_Get(list, i);
if (tmp == NULL)
{
return ;
}
printf("age:%d \n", tmp->age);
} //删除链表结点
while (LinkList_Length(list) > )
{
Teacher *tmp = (Teacher *)LinkList_Delete(list, );
if (tmp == NULL)
{
return ;
}
printf("age:%d \n", tmp->age);
} LinkList_Destroy(list); printf("hello...\n");
system("pause");
return ;
}

C_数据结构_链表的链式实现的更多相关文章

  1. c_数据结构_链表

    #include<stdio.h> #include<stdlib.h> #define ERROR 0 #define OK 1 #define OVERFLOW -2 ty ...

  2. C语言实现链表(链式存储结构)

    链表(链式存储结构)及创建 链表,别名链式存储结构或单链表,用于存储逻辑关系为 "一对一" 的数据.与顺序表不同,链表不限制数据的物理存储状态,换句话说,使用链表存储的数据元素,其 ...

  3. javascript实现数据结构:线性表--线性链表(链式存储结构)

    上一节中, 线性表的顺序存储结构的特点是逻辑关系上相邻的两个元素在物理位置上也相邻,因此可以随机存取表中任一元素,它的存储位置可用一个简单,直观的公式来表示.然后,另一方面来看,这个特点也造成这种存储 ...

  4. C++实现链队类——合肥工业大学数据结构实验5:链式队列

    实验5 5.1 实验目的 熟练掌握队列的顺序链式存储结构. 熟练掌握队列的有关算法设计,并在链队列上实现. 根据具体给定的需求,合理设计并实现相关结构和算法. 5.2 实验要求 5.2.1链队列实验要 ...

  5. c_数据结构_队的实现

    # 链式存储#include<stdio.h> #include<stdlib.h> #define STACK_INIT_SIZE 100//存储空间初始分配量 #defin ...

  6. C_数据结构_链式二叉树

    # include <stdio.h> # include <malloc.h> struct BTNode { int data; struct BTNode * pLchi ...

  7. 数据结构-线性表的链式存储相关算法(C语言实现)

    链表的简单介绍 为什么需要线性链表 当然是为了克服顺序表的缺点,在顺序表中,做插入和删除操作时,需要大量的移动元素,导致效率下降. 线性链表的分类 按照链接方式: 按照实现角度: 线性链表的创建和简单 ...

  8. c_数据结构_图_邻接表

    课程设计------邻接表 图的遍历实现课程设计:https://files.cnblogs.com/files/Vera-y/图的遍历_课程设计.zip #include<stdio.h> ...

  9. 阶段1 语言基础+高级_1-3-Java语言高级_04-集合_04 数据结构_4_数据结构_链表

    查询慢,增删快. 绿色代表一条链 红色是另外一条链 .查询是从头开始查所以慢. 在300和55之间添加一个元素

随机推荐

  1. 几款JS地图插件比较

    因工作需要,最近研究几款关于地图的JS插件,现与大家分享一下. 以下比较只是浅层次的分析一下,并没有实际通过项目检验,所以不足之处还请大家指出. 地图插件对比 插件名  简介 区域支持 扩展性 离线支 ...

  2. Path类型的扩展方法 z

    写了一个基于System.IO.Path类型方法的扩展类型,用于快速对文件系统路径进行操作.如下图: 其中有许多方法就是直接调用Path类型的静态方法.比如AppendPath方法内部会直接调用Pat ...

  3. HDU 5603 the soldier of love 离线+树状数组

    这是bestcorder 67 div1 的1003 当时不会做 看了赛后官方题解,然后翻译了一下就过了,而且速度很快,膜拜官方题解.. 附上官方题解: the soldier of love 我们注 ...

  4. ASP.NET Web API 如何通过程序控制返回xml还是json

    雖然 ASP.NET Web API 內建支援 JSON 與 XML 兩種輸出格式,並依據瀏覽器端送出的 Accept 標頭自動決定回應的內容格式,不過有時候我們的確也需要讓程式來控制要回應哪種格式, ...

  5. Flash AIR14导出ipa到Mac上的iOS模拟器测试

    没错!你没看错!俺这篇博客就是关于Flash AIR的! ----------------无聊的分割线------------------ 朋友最近学习Flash AIR for iOS开发,想找我帮 ...

  6. 【整理】C++虚函数及其继承、虚继承类大小

    参考文章: http://blog.chinaunix.net/uid-25132162-id-1564955.html http://blog.csdn.net/haoel/article/deta ...

  7. Timeout Detection & Recovery (TDR)

    Timeout Detection & Recovery (TDR) NVIDIA® Nsight™ Development Platform, Visual Studio Edition 2 ...

  8. ubuntu 13.04下sublime text 3使用中文输入法

    主要思路参考 http://blog.yanwen.org/archives/1955.html libsublime-imfix.so 这个库自己编译和从他这下载的 md5一样.可以不用编译了.直接 ...

  9. EDM

    今天,夏令营需要发推广EDM. 之前的edm都是文字版, 今天摸索了一下,简单写了些码, 效果还不错. 演示:http://baike.baidu.com/cms/s/bkcampus/summerc ...

  10. TextView & EditText

    TextView 1.下划线 textView.getPaint().setFlags(Paint. UNDERLINE_TEXT_FLAG ); //下划线 2.单独做第一步,文字会出现锯齿,要加下 ...