您的位置:首页 > 理论基础 > 数据结构算法

数据结构-实现单链表基本操作

2018-03-21 16:17 495 查看
首先要认识单链表:

单链表大致可以分为八种:

带头的,不带头的

带环的,不带环的

单向的,双向的



我实现的功能如下:

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;
}




pos前插入元素

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;
}
}




pos后面插入一个元素

void LinkListInsertAfter(LinkNode* pos, LinkType value)
{
if(pos==NULL)
{
return;
}
LinkNode* new_node=CreatNode(value);
new_node->next=pos->next;
pos->next=new_node;
}




不允许遍历,在pos前插入元素

将前插转换为后插问题,再将这两个节点的值交换

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);
}




时间复杂度:O(1)

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);
}


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: