linklist.h
#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
linklist.cpp
注意相应的句柄的定义 TLinkList
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.h"
typedef struct _tag_LinkList
{
int length;
LinkListNode header; //链表的头部
}TLinkList; //定义一个底层的句柄
LinkList* LinkList_Create()
{
TLinkList* ret = (TLinkList*)malloc(sizeof(TLinkList));
memset(ret, 0, sizeof(TLinkList));
ret->length = 0;
ret->header.next = NULL; //链表头部指向的下一个为NULL
return ret;
}
void LinkList_Destroy(LinkList* list) //释放内存
{
if (list != NULL)
{
free(list);
list = NULL;
}
}
void LinkList_Clear(LinkList* list) //初始化
{
TLinkList* tList = NULL;
if (list == NULL)
{
return;
}
tList = (TLinkList*)list;
tList->length = 0;
tList->header.next = NULL;
}
int LinkList_Length(LinkList* list)
{
int ret = 0;
TLinkList* tList = NULL;
if (list == NULL)
{
ret = -1;
printf("func LinkList_Length() err: %d\n", ret);
return ret;
}
tList = (TLinkList*)list;
return tList->length;
}
int LinkList_Insert(LinkList* list, LinkListNode* node, int pos)
{
int ret = 0, i = 0;
TLinkList* tList = NULL;
LinkListNode* current;
if (list == NULL || node == NULL || pos < 0)
{
ret = -2;
printf("func LinkList_Insert() err: %d\n", ret);
return ret;
}
tList = (TLinkList*)list;
current = &(tList->header); //重点:让辅助指针变量指向链表头部
for (i = 0; i < pos && (current->next != NULL); i++) //防止pos位置太大,超过链表长度
{
current = current->next; //跳pos次,让current指向插入位置前节点
}
//1 让node连接后续链表
node->next = current->next; //链表是单向的,3号位置保存在2号位置的next域中
//2 让前面的节点连接到新的node节点
current->next = node;
tList->length++;
return ret;
}
LinkListNode* LinkList_Get(LinkList* list, int pos)
{
int i = 0;
LinkListNode* ret = NULL;
TLinkList* tList = NULL;
LinkListNode* current;
if (list == NULL || pos < 0)
{
printf("func LinkList_Get() err: %d\n", ret);
return ret;
}
tList = (TLinkList*)list;
current = &(tList->header); //重点:让辅助指针变量指向链表头部
for (i = 0; i < pos && (current->next != NULL); i++) //防止pos位置太大,超过链表长度
{
current = current->next; //跳pos次,让current指向插入位置前节点
}
return current->next;
}
LinkListNode* LinkList_Delete(LinkList* list, int pos)
{
int i = 0;
LinkListNode* ret = NULL;
TLinkList* tList = NULL;
LinkListNode* current;
if (list == NULL || pos < 0)
{
printf("func LinkList_Delete() err: %d\n", ret);
return ret;
}
tList = (TLinkList*)list;
current = &(tList->header); //重点:让辅助指针变量指向链表头部
for (i = 0; i < pos && (current->next != NULL); i++) //防止pos位置太大,超过链表长度
{
current = current->next; //跳pos次,让current指向插入位置前节点
}
//1 缓存被删除的节点位置
ret = current->next;
//2 连接
current->next = ret->next; //这样删除到最后一个会出现ret=NULL而没有ret->next,引发异常?
tList->length--;
return ret;
}
测试框架
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "linklist.cpp"
typedef struct _Teacher
{
LinkListNode node; //(小结点LinkListNode与业务结点Teacher的函数入口地址重合),第一个域 第一个元素
int age;
char name[64];
}Teacher;
void main()
{
int ret = 0, i = 0;
int len = 0;
LinkList* list = NULL;
Teacher t1, t2, t3, t4, t5;
t1.age = 31;
t2.age = 32;
t3.age = 33;
t4.age = 34;
t5.age = 35;
list = LinkList_Create();//创建线性表
if (list == NULL)
{
printf("func SeqList_Create() ret:%d \n", ret);
return;
}
ret = LinkList_Insert(list, (LinkListNode*)&t1, 0); //头插法 插入线性表
ret = LinkList_Insert(list, (LinkListNode*)&t2, 0); //头插法
ret = LinkList_Insert(list, (LinkListNode*)&t3, 0); //头插法
ret = LinkList_Insert(list, (LinkListNode*)&t4, 0); //头插法
ret = LinkList_Insert(list, (LinkListNode*)&t5, 0); //头插法,所以t5是第一个
len = LinkList_Length(list);
//遍历
for (i = 0; i < len; i++)
{
Teacher* tmp = (Teacher*)LinkList_Get(list, i); //获取i号位置元素 0-4位置
if (tmp == NULL)
{
return;
}
printf("tmp->age: %d \n", tmp->age);
}
//删除元素
while (LinkList_Length(list) > 0) //此处不能用len替代,因为LinkList_Length(list)一直在变
{
Teacher* tmp = LinkList_Delete(list, 0); //从头部开始删除元素
if (tmp == NULL)
{
return;
}
printf("tmp->age: %d \n", tmp->age);
}
LinkList_Destroy(list);
system("pause");
}
注意点:
- 小结点LinkListNode与业务结点Teacher的连接问题
- 会分析相应技术场景图(图的绘画)