单链表

什么是链表

关于链表,百度百科 中有如下定义

链表是一种物理存储单元上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的。链表由一系列结点(链表中每一个元素称为结点)组成,结点可以在运行时动态生成。每个结点包括两个部分:一个是存储数据元素的数据域,另一个是存储下一个结点地址的指针域。

链表的优点

使用链表结构可以克服数组链表需要预先知道数据大小的缺点,链表结构可以充分利用计算机内存空间,实现灵活的内存动态管理。

链表的实现

实验编程
下面通过C语言实现单链表的 创建,头部插入,尾部插入,随意位置插入,移除结点,链表销毁,链表遍历功能

linklist.h

#ifndef _LINK_LIST_H_
#define _LINK_LIST_H_

#include <stdbool.h>



/* 定义结点 */
struct node
{
	int data;
	struct node* pNext;
};



/*
 * 函数名称:creat_node
 * 功能描述:创建结点
 * 返 回 值:结点指针
 */
struct node* creat_node(void);



/*
 * 函数名称:insert_node_from_head
 * 功能描述:从头部插入结点
 * 输入参数:pHead-链表头指针,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_from_head(struct node* pHead, int data);




/*
 * 函数名称:insert_node_from_tail
 * 功能描述:从尾部插入结点
 * 输入参数:pHead-链表头指针,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_from_tail(struct node* pHead, int data);




/*
 * 函数名称:insert_node_to_specified_location
 * 功能描述:从指定位置插入结点
 * 输入参数:pHead-链表头指针,loacation-要插入的位置,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_to_specified_location(struct node* pHead, int loacation, int data);




/*
 * 函数名称:remove_node
 * 功能描述:移除某个结点
 * 输入参数:pHead-链表头指针,data-删除结点对应的数据
 * 返 回 值:true-成功,false-失败
 */
bool remove_node(struct node* pHead, int data);



/*
 * 函数名称:linklist_print
 * 功能描述:遍历链表
 * 输入参数:pHead-链表头指针
 * 返 回 值:无
 */
void linklist_print(struct node* pHead);




/*
 * 函数名称:destroy_linklist
 * 功能描述:销毁链表
 * 输入参数:pHead-链表头指针
 * 返 回 值:无
 */
void destroy_linklist(struct node* pHead);





#endif

linklist.c

```#include "link_list.h"
#include <stdlib.h>
#include <stdio.h>


/*
 * 函数名称:creat_node
 * 功能描述:创建结点
 * 返 回 值:结点指针
 */
struct node* creat_node(void)
{
    struct node* pNode = (struct node*)malloc(sizeof(struct node));
    if (pNode != NULL)
    {
        pNode->data = 0;
        pNode->pNext = NULL;
        return pNode;
    }

    return NULL;
}



/*
 * 函数名称:insert_node_from_head
 * 功能描述:从头部插入结点
 * 输入参数:pHead-链表头指针,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_from_head(struct node* pHead, int data)
{
    struct node* pTmp = creat_node();
    if (pTmp == NULL)
        return false;

    pTmp->data = data;
    pTmp->pNext = pHead->pNext;

    pHead->pNext = pTmp;

    return true;
}




/*
 * 函数名称:insert_node_from_tail
 * 功能描述:从尾部插入结点
 * 输入参数:pHead-链表头指针,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_from_tail(struct node* pHead, int data)
{
    struct node* pTmp = pHead;

    struct node* pAdd = creat_node();
    if (pAdd == NULL)
        return false;

    pAdd->data = data;
    pAdd->pNext = NULL;

    while (pTmp->pNext != NULL)
    {
        pTmp = pTmp->pNext;
    }

    pTmp->pNext = pAdd;

    return true;
}




/*
 * 函数名称:insert_node_to_specified_location
 * 功能描述:从指定位置插入结点
 * 输入参数:pHead-链表头指针,loacation-要插入的位置,data-要插入的值
 * 返 回 值:true-成功,false-失败
 */
bool insert_node_to_specified_location(struct node* pHead, int loacation, int data)
{
    int i;

    struct node* pTmp = pHead;

    struct node* pAdd = creat_node();
    if (pAdd == NULL)
        return false;

    pAdd->data = data;
    pAdd->pNext = NULL;

    struct node* p = NULL;

    for (i = 0; i < loacation; i++)
    {
        pTmp = pTmp->pNext;
    }

    p = pTmp->pNext;
    pTmp->pNext = pAdd;
    pAdd->pNext = p;

    
    return true;
}




/*
 * 函数名称:remove_node
 * 功能描述:移除某个结点
 * 输入参数:pHead-链表头指针,data-删除结点对应的数据
 * 返 回 值:true-成功,false-失败
 */
bool remove_node(struct node* pHead, int data)
{
    struct node* pTmp = pHead;
    struct node* p = creat_node();
    if (p == NULL)
        return false;

    while (pTmp->pNext != NULL)
    {
        p = pTmp;
        pTmp = pTmp->pNext;

        if (pTmp->data == data)
        {
            p->pNext = pTmp->pNext;
            free(pTmp);
            return true;
        }
    }

    return false;
}





/*
 * 函数名称:linklist_print
 * 功能描述:遍历链表
 * 输入参数:pHead-链表头指针
 * 返 回 值:无
 */
void linklist_print(struct node* pHead)
{
    struct node* pTmp = pHead->pNext;

    printf("linklist: ");
    while (pTmp->pNext != NULL)
    {
        printf("%d ", pTmp->data);
        pTmp = pTmp->pNext;
    }

    printf("%d", pTmp->data);

    printf("\r\n");
}


/*
 * 函数名称:destroy_linklist
 * 功能描述:销毁链表
 * 输入参数:pHead-链表头指针
 * 返 回 值:无
 */
void destroy_linklist(struct node* pHead)
{
    struct node* pTmp, * pDel;

    pTmp = pHead;

    while (pTmp->pNext != NULL)
    {
        pDel = pTmp;
        free(pDel);
        pDel = NULL;

        pTmp = pTmp->pNext;
    }
}

main.c

#include <stdio.h>
#include "link_list.h"


int main(void)
{
	/* 创建链表头 */
	struct node* pListHeader = creat_node();
	if (pListHeader == NULL)
		return -1;

	printf("尾部插入\n");

	/* 插入数据 */
	int i = 0;
	for (i = 0; i < 10; i++)
		insert_node_from_tail(pListHeader, i + 1);

	linklist_print(pListHeader);

	printf("删除数据为5的结点\n");
	remove_node(pListHeader, 5);

	linklist_print(pListHeader);
	printf("\r\n");

	struct node* p = creat_node();
	
	printf("头部插入\n");
	for (i = 0; i < 10; i++)
		insert_node_from_head(p, i + 1);
	linklist_print(p);

	printf("\r\n");

	printf("在第5个位置插入数据为8的结点\n");
	insert_node_to_specified_location(p, 5, 8);
	
	linklist_print(p);

	destroy_linklist(pListHeader);
	destroy_linklist(p);

	return 0;
}

运行结果:
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lzg2021

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值