数据结构-单向链表-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;
}
相关推荐
Navigator_Z8 小时前
数据结构C //线性表(链表)ADT结构及相关函数
c语言·数据结构·算法·链表
蠢蠢的打码14 小时前
8584 循环队列的基本操作
数据结构·c++·算法·链表·图论
薯条不要番茄酱20 小时前
数据结构-3.链表
数据结构·链表
QXH2000001 天前
Leetcode—环形链表||
c语言·数据结构·算法·leetcode·链表
snowful world1 天前
vs2022链表的创建和打印(c语言版)
c语言·数据结构·链表
itoshi rin1 天前
简单题21 - 合并两个有序链表(Java)20240917
java·数据结构·链表
.普通人2 天前
c语言--力扣简单题目(链表的中间节点)讲解
c语言·leetcode·链表
Fabian!3 天前
代码随想录训练营Day3 | 链表理论基础 | 203.移除链表元素 | 707.设计链表 | 206.反转链表
数据结构·链表
时间幻灭‘3 天前
数据结构(2):LinkedList和链表[2]
数据结构·链表
QXH2000003 天前
数据结构—双向链表
c语言·数据结构·算法·链表