1.链式存储定义
为了表示每个数据元素与其直接后继元素之间的逻辑关系,每个元素除了存储本身的信息外,还需要存储指示其直接后继的信息
n个节点链接成一个链表,即为线性表的链式存储结构,因此链表的每个节点中只包含一个指针域,所以叫单链表。单链表正是通过每个节点的指针域将线性表中的数据元素按其逻辑次序链接在一起
2.
head.h
#pragma once
#include <crtdbg.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
typedef void LinkList;
typedef struct LinkListNode
{
struct LinkListNode* next;
}LinkListNode;
typedef struct HeadNode //头结点
{
LinkListNode head;
int length;
}HeadNode;
LinkList* LinkList_Create(); //创建链表
void LinkList_Destroy(LinkList *list); //销毁链表
void LinkList_Clear(LinkList *list); //清空链表
int LinkList_Length(LinkList *list); //链表的当前长度
void LinkList_Insert(LinkList *list, LinkListNode *node, int pos); //链表插入结点
LinkList* LinkList_Get(LinkList *list, int pos); //获取某位置结点
LinkList* LinkList_Delete(LinkList *list, int pos); //删除某位置结点
#include "Lin_Watch_Chain_Storage.h"
struct Teacher
{
LinkListNode* node;
int age;
char name[9];
};
LinkList* LinkList_Create() //创建链表
{
HeadNode *tlist = (HeadNode*)malloc(sizeof(HeadNode));
assert(tlist != NULL);
memset(tlist, 0, sizeof(HeadNode));
tlist->length = 0;
tlist->head.next = NULL;
return (LinkList*)tlist;
}
void LinkList_Destroy(LinkList *list) //销毁链表
{
HeadNode*tlist = (HeadNode*)list;
free(tlist);
}
void LinkList_Clear(LinkList *list) //清空链表
{
assert(list != NULL);
HeadNode*tlist = (HeadNode*)list;
tlist->length = 0;
tlist->head.next = NULL;
}
int LinkList_Length(LinkList *list) //链表的当前长度
{
assert(list != NULL);
HeadNode*tlist = (HeadNode*)list;
return tlist->length;
}
void LinkList_Insert(LinkList *list, LinkListNode *node, int pos) //链表插入结点
{
assert(list != NULL && node != NULL && pos >= 0);
HeadNode *tlist = (HeadNode*)list;
LinkListNode *pcur = &(tlist->head); //pcur指向头结点
for (int i = 0; i < pos && (pcur->next != NULL); i++) //pucr指向pos位置的前一个结点
{
pcur = pcur->next;
}
node->next = pcur->next; //新结点链接后继
pcur->next = node; //新节点链接前驱
tlist->length++;
}
LinkList* LinkList_Get(LinkList *list, int pos) //获取某位置结点
{
assert(list != NULL && pos >= 0);
HeadNode *tlist = (HeadNode*)list;
LinkListNode *pcur = &(tlist->head);
for (int i = 0; i < pos && (pcur->next != NULL); i++)
{
pcur = pcur->next;
}
return (LinkList*)pcur->next;
}
LinkList* LinkList_Delete(LinkList *list, int pos) //删除某位置结点
{
assert(list != NULL && pos >= 0);
HeadNode *tlist = (HeadNode*)list;
LinkListNode *pcur = &(tlist->head);
LinkListNode *tmp = NULL;
for (int i = 0; i < pos && (pcur->next != NULL); i++)
{
pcur = pcur->next;
}
tmp = pcur->next;
pcur->next = tmp->next;
tlist->length--;
return (LinkList*)tmp;
}
int main()
{
Teacher t1, t2, t3, t4, t5, t6;
t1.age = 21;
t2.age = 22;
t3.age = 23;
t4.age = 24;
t5.age = 25;
t6.age = 26;
LinkList *list = LinkList_Create();
printf("插入结点:\n");
LinkList_Insert(list, (LinkListNode*)&t1, 0);
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, 0);
for (int i = 0; i < LinkList_Length(list); i++)
{
Teacher *tmp = (Teacher*)LinkList_Get(list, i);
printf("tmp->age:%d ", tmp->age);
}
printf("\n");
printf("删除结点:\n");
LinkList_Delete(list, 0);
LinkList_Delete(list, 0);
LinkList_Delete(list, 0);
for (int i = 0; i < LinkList_Length(list); i++)
{
Teacher *tmp = (Teacher*)LinkList_Get(list, i);
printf("tmp->age:%d ", tmp->age);
}
printf("\n");
LinkList_Destroy(list);
_CrtDumpMemoryLeaks();
system("pause");
return 0;
}
原理图:
3.
优点:
无需一次性定制链表的容量
插入和删除操作无需移动数据元素
缺点:
数据元素必须保存后继元素的位置信息
获取指定数据的元素操作需要顺序访问之前的元素