数据结构-单向链表-002

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;
}
相关推荐
ChoSeitaku3 小时前
链表交集相关算法题|AB链表公共元素生成链表C|AB链表交集存放于A|连续子序列|相交链表求交点位置(C)
数据结构·考研·链表
香菜大丸3 小时前
链表的归并排序
数据结构·算法·链表
jrrz08283 小时前
LeetCode 热题100(七)【链表】(1)
数据结构·c++·算法·leetcode·链表
南宫生4 小时前
贪心算法习题其四【力扣】【算法学习day.21】
学习·算法·leetcode·链表·贪心算法
羊小猪~~15 小时前
数据结构C语言描述2(图文结合)--有头单链表,无头单链表(两种方法),链表反转、有序链表构建、排序等操作,考研可看
c语言·数据结构·c++·考研·算法·链表·visual studio
躺不平的理查德1 天前
数据结构-链表【chapter1】【c语言版】
c语言·开发语言·数据结构·链表·visual studio
半夜不咋不困1 天前
单链表OJ题(3):合并两个有序链表、链表分割、链表的回文结构
数据结构·链表
一颗星星辰2 天前
数据结构 | 题目练习第二章 | 合并两个有序链表 | 环形链表 | 环形链表入环第一个节点
网络·数据结构·链表
2401_858286112 天前
L6.【LeetCode笔记】合并两个有序链表
c语言·开发语言·笔记·leetcode·链表
攻城狮7号2 天前
【5.7】指针算法-快慢指针解决环形链表
数据结构·c++·算法·链表