混子数据结构学习之第二章线性表链式表示之基本操作插入

2022-01-16  本文已影响0人  那个混子

"磨棱角,褪优越,沉下心"
"不止于心动,更付诸于行动,执行力!“

前言

继续接着上一章的学习,本文主要还是记录链表的一些基本操作,主要是链表的清空、求链表长度、两种插入链表结点等一些操作,一方面是回顾这个链表的定义和使用,一方面需要去体会这些操作处理的逻辑思路。

链表的基本操作的补充

清空链表

理解:链表仍存在,但链表中无元素,成为空链表(头指针和头结点仍然在)。
注意的是和销毁的区别,清空链表还存在,销毁链表是不存在了。
算法思路:依次释放所有结点,保留头结点,并将头结点指针域设置为空。

代码实现

说明:

//-------单链表的清空:链表还存在
unsigned char ClearList(LinkList *L)//需要传入二级指针,等同于Node **L
{
    Node *p, *q;//或LinkList p, q;
    p = (Node*)(*L)->next;//存下首元结点的地址,当前的地址
    while(p)   
    {
        q =(Node*)p->next;//先保存当前的后面一个结点的地址
        free(p);//释放当前的结点
        p = q;//将后一个的结点地址赋值给p
    }
    (*L)->next = NULL;//头结点指针域为空 
    return OK;
}

求取链表的长度

概念:求取链表的有效结点个数。
算法:从首元结点开始进行依次判断计算,直道下一个结点为空即可;

代码实现

说明:

//------求单链表的长度
unsigned int ListLength(LinkList L)//这里不对链表进行值和地址的修改,传入一级指针即可!
{
    unsigned int i = 0;
    LinkList p =(LinkList) L->next; //读取首元结点

    while(p)//判断结点是否存在
    {
        i++;//计数
        p = (LinkList) p->next;//读取下一个结点
        //printf("第 %d 个结点\n",i);//测试使用的
    }

    //printf("统计结束\n");//测试使用的
    return i;
}

链表的创建(输入)

前面说了这种多操作,我们好像都没有学一下如何往链表中输入结点,这也就是创建各个结点。
有两种方法:头插法和尾插法

头插法

概念:
字面意思理解,就是从头部开始插入结点,这种方法是当前插入的结点永远是首元结点,也就是最先插入的结点在链表的最后位置。

实现步骤

代码实现

说明:

//------单链表的输入 法一(头插法)
unsigned char CreateListHead( LinkList* L, int n )
{
    LinkList p; //定义一个结点地址,用于存储
    int i,date;
    
    for(i=0; i<n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));//创建新结点

        printf("输入结点的数据:");
        scanf("%d",&date);
        p->date = date;

        p->next = (*L)->next;//这两句实现将结点P插入到L和L->next结点之间
        (*L)->next = p;

        printf("已完成插入第 %d 个结点\n",i+1);

    }
    return OK;
}

运行结果:

注意点

尾插法

概念:
类比头插法,尾插就是把新结点插到链表的尾端,当前插入的结点永远在尾端,先插入的都在表尾。把新加入的节点插入到上一个节点的尾部。
实现步骤:

代码实现

说明:

//------单链表的输入 法二(尾插法)
unsigned char CreateListTail( LinkList* L, int n )
{
    LinkList p; //定义一个结点地址,用于存储
    LinkList end;//定义一个结点,用来存储尾结点
    int i=0,date=0;

    end = (*L) ;//尾部结点(最开始没得结点,头结点可以认为是尾结点)
    
    for(i=0; i<n; i++)
    {
        p = (LinkList)malloc(sizeof(Node));//创建新结点

        printf("输入结点的数据:");
        scanf("%d",&date);
        p->date = date;//数据域赋值

        end->next = p;//将新结点挂到上一个尾结点的后面
        end = p;//end读取当前的尾结点

        printf("已完成插入第 %d 个结点\n",i+1);
    }

    end->next = NULL;//尾端结点的地址域清零

    return OK;
}

运行结果

过程问题点:

小结

今天这个就暂时记录到这里,后面查询删除这些后续重新开篇记录,不然篇幅有点大!
上述主要需要理解两种插入方式的思想,可能理解起来尾插法不太好理解,我自己学习理解就是自己画图,代入理解的,心里面想一下插入2个或者3个结点两种方法他是如何实现的,也很容易想明白!

参考资料:
青岛大学.王卓.数据结构与算法
《数据结构 C语言版》.严蔚敏
《大话数据结构》.程杰

若上述描述有问题或者歧义的,欢迎与我反馈交流,共同进步学习!

欢迎关注本人微信公众号:那个混子
记录自己学习的过程,分享乐趣、技术、想法、感悟、情感!
单片机类嵌入式交流学习可加企鹅群:120653336
上一篇 下一篇

猜你喜欢

热点阅读