1无头单向链表
2有头单向链表
2.1链表结点结构体定义
c
typedef struct link_node
{
int data;//数据域
struct link_node *pnext;//指向下一个结点的指针
}NODE;
2.2链表头结点结构体定义
c
typedef struct link_lable{
NODE *pnext;//指向首节点的指针
int clen;//记录链表节点数量
}LABLE;
2.3单向链表头结点创建
c
/*=============单向链表标签(头)创建-空链表=========*/
void *create_lable(void)
{
LABLE *pnew=NULL;
pnew=malloc(sizeof(LABLE));//创建一个标签
if (NULL == pnew)
{
perror("fail malloc");
return NULL;
}
/*初始化标签成员*/
pnew->pnext= NULL;//
pnew->clen=0;
return pnew;
}
2.4单向链表结点创建
c
/*=============单向链表结点创建==============*/
NODE * create_node(int data)
{
NODE *pnew=NULL;
pnew=malloc(sizeof(NODE));
if (NULL == pnew)
{
perror("fail malloc");
return NULL;
}
pnew->pnext=NULL;
pnew->data = data;
return pnew;
}
2.5链表非空判断
c
int is_empty_link(LABLE *list)
{
return NULL == list->pnext;
}
2.6单向链表结点插入
2.6.1头插法
c
/*=============单向链表头插法=================*/
int push_head(LABLE *list, NODE *pnode)
{
pnode->pnext = list->pnext;
list->pnext=pnode;
list->clen++;
return 0;
}
2.6.2尾插法
c
/*=============单向链表尾插法=================*/
int push_tail(LABLE *list,NODE *pnode)
{
NODE *ptmp=NULL;
if(is_empty_link(list))
{
list->pnext=pnode;
}
else
{
ptmp=list->pnext;//将结点类型的中间指针变量初始化为指向首结点
while(1)
{
if(NULL==ptmp->pnext)
{
break;
}
ptmp=ptmp->pnext;//不断指向下一个结点
}
pnode->pnext=ptmp->pnext;//新结点的指针域继承旧结点的指针域(NULL)
ptmp->pnext=pnode;//原链表的最后一个结点的指针域指针指向新插入的结点
}
list->clen++;
return 0;
}
2.7单向链表遍历
c
/*=============单向链表遍历===============*/
int list_for_each(LABLE *list)
{
NODE *ptmp=NULL;
ptmp=list->pnext;//将结点类型的中间指针变量初始化为指向首结点
while(1)
{
if(NULL==ptmp)//遍历到的当前结点为空(链表最后一个结点的后面的那个还没有被创建出来的结点)
{
break;
}
printf("%d\t",ptmp->data);
ptmp=ptmp->pnext;//不断指向下一个结点
}
printf("\n");
return 0;
}
注意:
该遍历操作,最终【ptmp】并不是指向链表最后一个结点,而是【NULL】,指尾节点后面那个还未被创建出来的结点。
2.7单向链表结点删除
2.7.1头删法
c
/*=============单向链表头删法=================*/
int pop_head(LABLE *list)
{
NODE *ptmp=NULL;
if(is_empty_link(list))
{
return 0;
}
ptmp=list->pnext;//初始化结点类型的中间指针变量为链表头指针域(即代表首结点,而非头结点)
list->pnext=ptmp->pnext;
free(ptmp);
list->clen--;
return 0;
}
2.7.2尾删法
c
/*=============单向链表尾删法=================*/
int pop_tail(LABLE *list)
{
NODE *ptmp=NULL;
if(is_empty_link(list))
{
return 0;
}
else if(1==list->clen)
{
free(list->pnext);
list->pnext=NULL;
}
else
{
ptmp=list->pnext;//将结点类型的中间指针变量初始化为指向首结点
while(1)
{
if(NULL==ptmp->pnext->pnext)
{
break;
}
ptmp=ptmp->pnext;//不断指向下一个结点
}
free(ptmp->pnext);//释放最后1个结点
ptmp->pnext=NULL;//将倒数第2个结点的指针域置空(因为它将成为新的尾结点),此时链表最后一个结点已被放逐
}
list->clen--;
return 0;
}
2.8单向链表查找
c
/*=============单向链表查找=================*/
NODE *search_link(LABLE *list,int data)
{
NODE *ptmp=NULL;
ptmp=list->pnext;//初始化结点类型的中间指针变量为链表头指针域(指向首结点)
while(1)
{
if(NULL==ptmp)
{
break;
}
if(data==ptmp->data)
{
return ptmp;
}
ptmp=ptmp->pnext;
}
return NULL;
}
2.9单向链表修改
c
int change_link_list(LABLE *list,int source_data,int target_data)
{
NODE *search=NULL;
search=search_link(list,source_data);
if(search!=NULL)
{
search->data=target_data;
return 0;
}
return -1;
}
2.10单向链表销毁
c
/*=============单向链表销毁=================*/
int destroy_link_list(LABLE *list)
{
while(1)
{
if(is_empty_link(list))
{
break;
}
else
{
pop_head(list);
}
}
free(list);
return 0;
}
1.11单向链表的其它操作
1.11.1单向链表逆序
c
/*============单向链表逆序=============*/
int reverse_link_list(LABLE *list)
{
NODE *ptmp=NULL;
NODE *pinsert=NULL;
if(is_empty_link(list))
{
return 0;
}
ptmp=list->pnext;//初始化结点类型的中间指针变量为链表头指针域(首结点)
list->pnext=NULL;//首结点的指针域赋值NULL
while(1)
{
if(NULL==ptmp)
{
break;
}
pinsert=ptmp;//待插入的结点
ptmp=ptmp->pnext;//不断指向下一个结点
pinsert->pnext=list->pnext;
list->pnext=pinsert;
}
return 0;
}
1.11.2单向链表查找中间结点
c
/*============在单向链表中寻找中间结点=============*/
NODE* search_midnode_link_list(LABLE *list)
{
NODE *fast=NULL;
NODE *slow=NULL;
/*初始化快慢指针为头结点的指针域(指向首结点)*/
slow=list->pnext;
fast=slow;
while(1)
{
if(NULL==fast)
{
break;
}
fast=fast->pnext;
if(NULL==fast)
{
break;
}
fast=fast->pnext;
slow=slow->pnext;
}
return slow;
}
1.11.3单向链表查找倒数第k个结点
c
/*============在单向链表中寻找倒数第K个结点=============*/
NODE *search_last_k_link_list(LABLE *list,int k)
{
NODE *p_fast=NULL;
NODE *p_slow=NULL;
p_fast=list->pnext;
p_slow=p_fast;
for(int i=0;i<k;i++)
{
if(NULL==p_fast)
{
return NULL;
}
p_fast=p_fast->pnext;
}
while(1)
{
if(NULL==p_fast)
{
break;
}
p_fast=p_fast->pnext;
p_slow=p_slow->pnext;
}
return p_slow;
}