数据结构-单向链表-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;
}
相关推荐
疯狂成瘾者9 天前
Java 集合 LinkedList 详解:链表结构、常用方法和队列使用
java·开发语言·链表
WL学习笔记9 天前
单项不带头不循环链表
数据结构·链表
拳里剑气10 天前
C++算法:链表
c++·算法·链表
CoderYanger10 天前
A.每日一题:2095. 删除链表的中间节点
java·数据结构·程序人生·leetcode·链表·面试·职场和发展
CoderYanger10 天前
A.每日一题:234. 回文链表
数据结构·程序人生·leetcode·链表·面试·职场和发展·学习方法
影视飓风TIM10 天前
数据结构 | 链表超全笔记(单链表+双链表+高频算法题)
数据结构·笔记·链表
玖玥拾10 天前
C/C++ 数据结构(六)链表迭代器与底层
c语言·数据结构·c++·链表·stl库
IronMurphy10 天前
【算法五十八】23. 合并 K 个升序链表
数据结构·算法·链表
学计算机的计算基10 天前
链表算法上篇:LeetCode 206/234/141/142/160/21 题解与易错点
java·笔记·算法·链表
Tisfy10 天前
LeetCode 2095.删除链表的中间节点:两次遍历 / 一次遍历(快慢指针)
算法·leetcode·链表·题解·双指针