首先要认识单链表:
单链表大致可以分为八种:
带头的,不带头的
带环的,不带环的
单向的,双向的
我实现的功能如下:
void LinkListInit(LinkNode** phead);//初始化链表
void LinkListPrintChar(LinkNode* head,const char* msg);//打印链表
void LinkListPushBack(LinkNode** phead, LinkType value);//尾插
void LinkListPopBack(LinkNode** phead);//尾删
void LinkListPushFront(LinkNode** phead, LinkType value); //头插
void LinkListPopFront(LinkNode** phead); //头删
LinkNode* LinkListFind(LinkNode* head, LinkType to_find);//查找元素地址
void LinkListInsert(LinkNode** head, LinkNode* pos, LinkType value);//pos前插入
void LinkListInsert2(LinkNode** phead, LinkNode* pos, LinkType value);//不允许遍历链表, 在 pos之前插入
void LinkListInsertAfter(LinkNode* pos, LinkType value); //pos后插入
void LinkListErase(LinkNode** phead, LinkNode* pos); //删除指定地址的元素
实现如下:
初始化因为要使头指针指向空,所以
19 void LinkListInit(LinkNode** phead)
20 {
21 if(phead==NULL)
22 {
23 return;
24 //非法输入
25 }
26 *phead=NULL;
27 }
与顺序表基本相似,注意对指针的处理。
void LinkListPushBack(LinkNode** phead, LinkType value)
{
if(phead==NULL)
{
return;
}
if(*phead==NULL)
{
//空链表
LinkNode* new_node=CreatNode(value);
*phead=new_node;
return;
}
//链表非空的情况
LinkNode* cur=*phead;
while(cur->next!=NULL)
{
cur=cur->next;
}
LinkNode* new_node=CreatNode(value);
cur->next=new_node;
}
void LinkListPopBack(LinkNode** phead)
{
if(phead==NULL)
{
return;
}
if(*phead==NULL)
{
//空链表无法删除
return;
}
if((*phead)->next==NULL)
{
DestroyNode(*phead);
*phead=NULL;
return;
}
LinkNode* cur=*phead;
LinkNode* pre=NULL;
while(cur->next!=NULL)
{
pre=cur;
cur=cur->next;
}
DestroyNode(cur);
pre->next=NULL;
}
void LinkListPushFront(LinkNode** phead, LinkType value)
{
if(phead==NULL)
{
return;
}
LinkNode* new_node=CreatNode(value);
new_node->next=*phead;
*phead=new_node;
}
void LinkListPopFront(LinkNode** phead)
{
if(phead==NULL)
{
return;
}
LinkNode* cur=*phead;
*phead=(*phead)->next;
DestroyNode(cur);
}
成功:返回元素的地址
失败:返回NULL
LinkNode* LinkListFind(LinkNode* head, LinkType to_find)
{
if(head==NULL)
{
return;
}
LinkNode* cur=head;
for(;cur!=NULL;cur=cur->next)
{
if(cur->data==to_find)
{
return cur;
}
}
return NULL;
}
void LinkListInsert(LinkNode** phead, LinkNode* pos, LinkType value)
{
if(phead==NULL||pos==NULL)
{
return;
}
if(*phead==pos)
{
LinkListPushFront(phead,value);
return;
}
LinkNode* cur=*phead;
while(cur!=NULL)
{
//printf("进入此\n");
if(cur->next==pos)
{
LinkNode* new_node=CreatNode(value);
cur->next=new_node;
new_node->next=pos;
return;
}
cur=cur->next;
}
}
void LinkListInsertAfter(LinkNode* pos, LinkType value)
{
if(pos==NULL)
{
return;
}
LinkNode* new_node=CreatNode(value);
new_node->next=pos->next;
pos->next=new_node;
}
将前插转换为后插问题,再将这两个节点的值交换
void LinkListInsert2(LinkNode** phead, LinkNode* pos, LinkType value)
{
if(phead==NULL)
{
return;
}
LinkListInsertAfter(pos,value);
LinkType tmp=pos->data;
pos->data=pos->next->data;
pos->next->data=tmp;
}
时间复杂度:O(n^2)
void LinkListErase(LinkNode** phead, LinkNode* pos)
{
if(phead==NULL||pos==NULL)
{
return;
}
if(*phead==NULL)
{
return;//空链表
}
if(*phead==pos)
{
LinkListPopFront(phead);
return;
}
LinkNode* cur=*phead;
while(cur!=NULL)
{
if(cur->next==pos)
break;
cur=cur->next;
}
if(cur->next==NULL)
{
return;
}
cur->next=pos->next;
DestroyNode(pos);
}
void LinkListErase2(LinkNode** phead, LinkNode* pos)
{
if(phead==NULL)
{
return;
}
if(*phead==NULL)
{
return;
}
LinkNode* to_destroy=pos->next;
pos->data=pos->next->data;
pos->next=pos->next->next;
DestroyNode(to_destroy);
}
void LinkListRemove(LinkNode** phead, LinkType to_delete)
{
if(phead==NULL)
{
return;
}
if(*phead==NULL)
{
return;//空链表
}
LinkNode* pos=NULL;
pos=LinkListFind(*phead,to_delete);
LinkListErase(phead,pos);
链表为空,返回1
链表非空,返回0
int LinkListEmpty(LinkNode* head)
{
if(head==NULL)
{
return 1;
}
else
{
return 0;
}
}
返回链表元素的个数
size_t LinkListSize(LinkNode* head)
{
size_t count=0;
LinkNode* cur=head;
for(;cur!=NULL;cur=cur->next)
{
count++;
}
return count;
}
void LinkListReversePrint(LinkNode* head)
{
if(head==NULL)
{
return;
}
if(head==NULL)
{
return;
}
LinkListReversePrint(head->next);
printf("[%c|%p] ",head->data,head);
}