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

如题,本菜鸡也是初学数据结构,由于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;
}
    原文作者:五柯是个小菜鸡
    原文地址: https://www.jianshu.com/p/1abc020b84b7
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞