自学嵌入式 day19-数据结构 链表
二、线性表的链式存储
1.特点:
(1)线性表链式存储结构的特点是一组任意的存储单位存储线性表的数据元素,存储单元可以是连续的,也可以不连续。可以被存储在任意内存未被占用的位置上。
(2)所以前面的顺序表只需要存储数据元素信息就可以了。在链式结构中还需要一个元素存储下一个元素的地址。
(3)为了表示每个数据元素,ai与其直接后继数据元素ai+1之间的逻辑关系,对ai来说,除了存储其本身的信息外,还需要存一个指示器直接后续的信息。把存储元素信息的域叫数据域,把存储直接后继位置的域叫指针域。这两部分信息组成数据元素ai的存储映像,叫结点(Node);
2.链表结构:
3.链表的常规操作
(1)创建链表
LinkList *CreateLinkList()
{
LinkList *ll = malloc(sizeof(DATATYPE));//分配链表表头结点内存空间
if(NULL == ll)判断是否申请成功
{
fprintf(stderr,"GreateLinkList malloc");
return NULL;
}
ll -> head = NULL;初始化头指针
ll -> clen = 0;初始化链表长度
return ll;
}
(2)头部插入
①newnote == NULL
②newnote != NULL
int IsEmpLinkList(LinkList *ll)//判断链表是否为空
{
return ll -> clen == 0;
}int InsertHeadLinkList(LinkList *ll,DATATYPE *data)
{
LinkNote *newnote = malloc(sizeof(LinkNote));//申请新节点内存空间
if(NULL == newnote)//判断是否申请成功
{
fprintf(stderr,"IsEmpLinkList malloc");
return 1;}
memcpy(&newnote -> data,data,sizeof(DATATYPE));//复制数据到节点
newnote -> next = NULL;//将结点next初始化为空指针
if(IsEmpLinkList(ll))//判断链表是否为空
{
ll -> head = newnote;//将头指针指向新结点
}
else
{
newnote -> next = ll -> head;//将新结点的next指向头指针,即指向原链表的头元素地址
ll -> head = newnote; //将头指针指向新结点
}
ll -> clen++;//链表长度+1
return 0;
}
(3)遍历
int GetSizeofLinkList(LinkList *ll)//获取链表长度
{
return ll -> clen;
}int ShowLinkList(LinkList *ll)
{
int len = GetSizeofLinkList(ll);
LinkNote *tmp = ll -> head;//定义新结点并指向头指针
int i;
for(i = 0;i < len;++i)//遍历循环链表
{
printf("%s,%c,%d,%d\n",tmp -> data.name,tmp -> data.sex,tmp -> data.age,tmp -> data.score);
tmp = tmp -> next;//将tmp指向下一个结点
}
return 0;
}
(4)查找
DATATYPE *FindLinkList(LinkList *ll,char *name)
{
LinkNote *tmp = ll -> head;
while(tmp)
{
if(0 == strcmp(tmp -> data.name,name))//判断是否是需要找的结点
{
return &tmp -> data;
}
tmp = tmp -> next;
}
return NULL;
}
(5)删除
int DeleteLinkList(LinkList* ll, char* name)
{
LinkNode* tmp = ll->head;//创建临时指针指向链表头
if (IsEmptyLinkList(ll))//判断链表是否为空
{
return 1;
}
if (0 == strcmp(tmp->data.name, name))//判断所删结点是否为头节点
{
ll->head = ll->head->next;//将头指针指向头节点的next
free(tmp);//释放头结点空间
ll->clen--;//链表个数-1
return 0;
}
while (tmp->next)//所删结点不是头结点
{
if (0 == strcmp(tmp->next->data.name, name))//遍历查找所删结点
{//将所删结点的前后连接起来
LinkNode* tmp2 = tmp->next;
tmp->next = tmp->next->next;
free(tmp2);
ll->clen--;
return 0;
}
tmp = tmp->next;
}
return 1;
}