单链表操作C语言实现详细注释

作者: 五柯是个小菜鸡 | 来源:发表于2019-04-12 09:51 被阅读2次

如题,本菜鸡也是初学数据结构,由于C语言基础不扎实,遇到了很多问题,网上的资料基本只有代码没有详细注释,自己学习的过程有些麻烦。为了方便后面的同学,同时为自己总结一下,便发出来。不过毕竟个人能力有限,如有注释错误曲解,望大神们与我进行讨论指教。

#include<stdio.h>
#include<stdlib.h>
#define chushichangdu 5

/*1.在这里,结点概念和地址概念可理解为是相通的*/
/*2.所谓遍历,因为链表的存储结构并非连续,
因此无法直接向数组那样拿出目标位置的数据项进行操作,
只能通过指针域的连锁关系进行遍历来找到第几个项进行操作*/
/*3.return函数可停止函数,然后直接进行return输出*/
/*4.由于temp是移动到待处理结点的前一个结点,
因此无法直接处理待处理的数据域和指针域,
需要将待处理结点的地址赋给一个临时结点,然后处理结点即可*/

typedef struct xian//定义结构体——xian的构成成分
{
    int data;//数据域
    struct xian *next;//指针域
}xian;//至此,xian成为一种类型,这个类型的变量由一个内容数据和一个地址指针构成

xian *chushihua()//初始化函数(包括头结点,头指针,链表初始数据)
{
    xian *touzhizhendizhi=(xian*)malloc(sizeof(xian));//通过分配内存来创建头指针的地址
    xian *temp=touzhizhendizhi;//创建一个指针变量以遍历链表,也就是个用以交换保存的临时变量
    for(int i=1;i<=chushichangdu;i++)//输入链表的初始数据,也可以设置为手动键入
    {
        xian *a=(xian*)malloc(sizeof(xian));//创建链表的下一个新结点(即该结点的地址)
        a->data=i;//(将i值赋给此处结点的数据域,也可赋其它值)
        a->next=NULL;//此处结点的指针域设置为空(即链表尾结点的结束标志),表示目前链表结点的最后一位
        temp->next=a;//将a这个地址指针放在临时变量temp中进行保存(因为for的下一个循环会创建新的a地址指针)
        temp=temp->next;//将临时变量temp后移以配合后续结点的创建和初始数据生成
    }
    return touzhizhendizhi;//返回值为链表的头指针地址,也就是新链表,在主函数中要赋给原链表(即以此作为链表进行操作)
}

xian *charu(xian *touzhizhendizhi,int daichayuansu,int charuweizhi)//插入函数
{
    xian *temp=touzhizhendizhi;//创建临时指针变量并将头指针赋给它以遍历链表
    for(int i=1;i<charuweizhi;i++)//先通过for循环进行遍历找到对应位置的项
    {
        if(temp->next==NULL)//由于上面已经将头指针赋给了temp,所以此处表示头指针为空,说明没有首元结点,这是一个空链表
        {
            printf("这里不可以噢!\n");//因为一个元素位置都没有,因此无法插入
            return touzhizhendizhi;
        }
        temp=temp->next;//进行temp遍历以跟随for循环直到找到目标位置,最终temp为待插位置的前一项
    }//for循环结束,即已经到了待插入位置
    xian *xinjiedian=(xian*)malloc(sizeof(xian));//创建新结点用来放待插入的数据元素
    xinjiedian->data=daichayuansu;//将待插入元素插入新结点的数据域
    xinjiedian->next=temp->next;//将待插位置的地址放在新结点的指针域,即将新结点与待插位置以及其后面的结点串进行连接
    temp->next=xinjiedian;//将新结点的地址放在插入位置的前一个结点的指针域里,即将新结点与前面的结点串进行连接
    return touzhizhendizhi;//返回值为链表的头指针地址,也就是新链表,在主函数中要赋给原链表(即以此作为链表进行操作)
}

xian *shanchu(xian *touzhizhendizhi,int daishanweizhi)//删除函数
{
    xian *temp=touzhizhendizhi;//创建临时结点用以遍历
    for(int i=1;i<daishanweizhi;i++)//遍历使temp抵达待删位置的前一个结点
    {
        if(temp->next==NULL)
        {
            printf("这里不可以噢!");
            return touzhizhendizhi;
        }
        temp=temp->next;//temp后移进行遍历
    }
    xian *cunchujiedian=temp->next;//将待删结点的地址赋给存储结点,即存储结点就是待删结点,这样才能对待删结点的指针域进行便捷操作
    temp->next=cunchujiedian->next;//将待删结点的指针域赋给前一个结点,即跳过待删结点,将待删结点前后两个结点进行连接
    free(cunchujiedian);//释放存储节点的内存,即不但将其从链表中剔除,且彻底从计算机中删除
    return touzhizhendizhi;//返回值为链表的头指针地址,也就是新链表,在主函数中要赋给原链表(即以此作为链表进行操作)
}

int chazhao(xian *touzhizhendizhi,int daizhaoshuju)//查找函数
{
    xian *temp=touzhizhendizhi;
    int i=1;
    while(temp->next)//指针域不为空时进行循环,即非尾结点时
    {
        temp=temp->next;//temp临时结点进行后移
        if(temp->data==daizhaoshuju)//如果此结点处的数据就是待找数据
            return i;//返回待找数据的位置
        i++;//还没找到则位置数+1
    }
    return -1;//返回值为-1表示int型函数执行失败
}

xian *genggai(xian *touzhizhendizhi,int xiugaiweizhi,int xinshuju)//更改函数
{
    xian *temp=touzhizhendizhi;
    for(int i=1;i<xiugaiweizhi;i++)
    {
        if(temp->next==NULL)
        {
            printf("这里不可以噢!");
            return touzhizhendizhi;
        }
        temp=temp->next;
    }
    xian *linshijiedian=temp->next;//建立临时结点
    linshijiedian->data=xinshuju;//赋予更改数据
    return touzhizhendizhi;//返回值为链表的头指针地址,也就是新链表,在主函数中要赋给原链表(即以此作为链表进行操作)
}

void display(xian *touzhizhendizhi)//输出函数
{
    xian *temp=touzhizhendizhi;
    while(temp->next)
    {
        temp=temp->next;//因为一开始temp位于没有数据域的头指针,所以先后移再输出打印数据域,即打印while条件中所用结点的下一个结点的数据域
        printf("%d",temp->data);
    }
    printf("\n");
}

int main()//函数调用示例
{
    int weizhi;//定义一个变量用以放置查找函数的返回值结果
    xian *touzhizhendizhi=chushihua();//初始化将链表(确定头指针、各结点的数据域和指针域)
    display(touzhizhendizhi);
    touzhizhendizhi=charu(touzhizhendizhi,9,3);//将第3位置插入数据 9
    display(touzhizhendizhi);
    touzhizhendizhi=shanchu(touzhizhendizhi,5);//将第5位置的数据删除
    display(touzhizhendizhi);
    printf("%d\n",chazhao(touzhizhendizhi,3));//查找数字3的位置
    touzhizhendizhi=genggai(touzhizhendizhi,2,7);//将第2位置的数据改为7
    display(touzhizhendizhi);

    return 0;
}

相关文章

  • 单链表操作C语言实现详细注释

    如题,本菜鸡也是初学数据结构,由于C语言基础不扎实,遇到了很多问题,网上的资料基本只有代码没有详细注释,自己学习的...

  • 单链表的C语言算法实现

    单链表的C语言算法实现 自己用C语言实现的单链表算法,有什么不正确的地方,请各位共同讨论与指正。

  • 链表

    单链表 C实现 Java实现 双链表 C实现 Java实现

  • 单链表算法题整理(思路详解)

    前一篇文章中记录了单链表的实现和基本操作,在此基础上,本次整理了单链表的相关常见算法题的思路和C语言实现,留作复习...

  • 数据结构与算法之链表(五)双链表实现

    引言 前面几篇文章详细学习了单链表的操作,有了这个基础,双链表的实现便水到渠成。由于它的基本实现和单链表基本一样,...

  • 链式存储结构的线性表

    单链表结构可用如下C语言代码描述 建立链表操作 读取操作 插入节点操作 删除一个节点操作 遍历操作 链式存储结构线...

  • DS单链表--类实现

    题目描述 用C++语言和类实现单链表,含头结点 属性包括:data数据域、next指针域 操作包括:插入、删除、查...

  • 单链表实现(C语言)

    单链表是由结构体、指针相结合的一种数据格式, 看个简单的结构体,格式如下: 这个结构体只存放了一个int的数据类型...

  • C语言-单链表的实现和操作

    定义 遍历 创建 搜索 长度 增(append) 增(insert) 删(index>0) 反转 复制

  • C++实现双向循环链表

    本次博文是关于利用C++模板的方式实现的双向循环链表以及双向循环链表的基本操作,在之前的博文C++语言实现双向链表...

网友评论

    本文标题:单链表操作C语言实现详细注释

    本文链接:https://www.haomeiwen.com/subject/qosqwqtx.html