C_数据结构_链表的链式实现
传统的链表不能实现数据和链表的分离,一旦数据改变则链表就不能用了,就要重新开发。
如上说示:外层是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, 0, sizeof(TLinkList)); tmp->length = 0; 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 = 0; return ; } int LinkList_Length(LinkList* list) //O(1) { TLinkList *tList = NULL; tList = (TLinkList *)list; if (tList == NULL) { return -1; } return tList->length; } int LinkList_Insert(LinkList* list, LinkListNode* node, int pos) //在pos位置插入节点,先连接后面的再连接前面的。 { int i = 0; LinkListNode *current = NULL; TLinkList *tList = NULL; if (list==NULL || node==NULL || pos<0)//node为新节点 { return -1; } tList = (TLinkList *)list; current = &(tList->header);//节点要取地址给指针 for (i=0; i<pos; i++)//链表节点序号从0开始 { current = current->next;//current为pos位置前面的节点 } //先连接后面节点在连接前面节点 node->next = current->next; //前面的链表 连接 新结点 current->next = node; tList->length ++; return 0; } LinkListNode* LinkList_Get(LinkList* list, int pos) //O(n) { int i = 0; LinkListNode *current = NULL; TLinkList *tList = NULL; tList = (TLinkList *)list; if (list==NULL || pos<0) { return NULL; } current = &(tList->header); //赋值指针变量初始化 for (i=0; i<pos; i++) { current = current->next; } return current->next; } LinkListNode* LinkList_Delete(LinkList* list, int pos) //O(n) { int i = 0; LinkListNode *current = NULL; LinkListNode *ret = NULL; TLinkList *tList = NULL; tList = (TLinkList *)list; if (list==NULL || pos<0) { return NULL; } current = &(tList->header); for (i=0; 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[32]; int age ; }Teacher; void main() { LinkList *list = NULL; int i = 0; Teacher t1, t2, t3, t4, t5, t6;//main函数结束这几个变量释放 t1.age = 31; t2.age = 32; t3.age = 33; t4.age = 34; t5.age = 35; t6.age = 36; list = LinkList_Create(); //思考1: 业务节点 和 链表算法是如何分离 //思考2: 业务节点的生命周期 归谁管... //插入元素 LinkList_Insert(list, (LinkListNode *)&t1, 0);//t1地址和node地址是重叠的 LinkList_Insert(list, (LinkListNode *)&t2, 0); LinkList_Insert(list, (LinkListNode *)&t3, 0); LinkList_Insert(list, (LinkListNode *)&t4, 0); LinkList_Insert(list, (LinkListNode *)&t5, 0); LinkList_Insert(list, (LinkListNode *)&t6, 3); //遍历链表 for (i=0; 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) > 0) { Teacher *tmp = (Teacher *)LinkList_Delete(list, 0); if (tmp == NULL) { return ; } printf("age:%d \n", tmp->age); } LinkList_Destroy(list); printf("hello...\n"); system("pause"); return ; }