数据结构之链表的插入操作
这是我这名初级程序猿第一次写博客,本人可能由于技术不够,技术文章中可能有很多瑕疵,请大家多多指教,好了,开始介绍数据结构的初级(c++语言描述)。
想要对链表了解的透彻,必须要对指针了如指掌,指针还真是挺难理解的,我刚开始学指针的时候,是真的晕针,那种就是思维上的煎熬,但是再难,也坚持了下来,相信大家对指针的了解程度应该比我深。
有很多链表有头节点,也有很多没有头节点,在有头节点的链表中,头节点内是不存放内容的,好了,现在先定义一个结构体。
struct stunode { char name[5]; // 姓名 int age; // 年龄
stunode* next; // 指向下一个节点 };
结构体已经定义好了,接下来就是建立链表了,
咱们先来说一下插入节点,在插入节点的算法中,分为头插入还有尾插入两种,先来说一下尾插入。在头插入中,定义了一个函数,如下
void createlinklist(stunode* &head, stunode* &end) { stunode* stu = new stunode(); // 1 std::cin >> stu->name; // 2 std::cin >> stu->age; // 3 stu->next = null; // 4
if (head == null) { head = stu;// 6 end = stu; //7 } else { end->next = stu; // 8 end = stu; // 9 } }
解释一下函数的参数,传入的指针引入类型,head就是链表的头指针,end是链表的尾指针。可能一些人建立链表时不使用尾指针,用尾指针会简化很多插入的操作,我个人建议使用尾指针,这样也便于理解。
在标号为2的那一行代码中,动态开辟了一个结构体,这个是在堆中开辟的,等链表用完之后要记得释放,稍后会详细的介绍。第2行,第3行中,就是对数据进行输入,这个没有过多的解释。第4行要将着重解释一下。先来看一下这张图
为了防止此节点中的next指针建立之后变成野指针,就需要将此节点的next指针提前赋值为null;其实这也是一种习惯,定义变量一定要赋初始值。
接下来这几行就是代码的核心了,当head为空时,就需要将head指针指向刚刚建立节点,然后再将end指针也只向新建立的节点,这是程序中还没有节点的情况。当程序中存在节点时,就是else那种情况,就需要一点小技巧了。
黑色笔线部分就是没有进入else之前的部分,当进入else时,就要将当前的end指向的节点的next指针赋值为新建立的节点地址,,因为end要一直指向链表的尾部,所以就要将end向后移动一位,使end指向新建立的节点,此时,尾加入就完成了,如果你此时还没有想明白,那多看看图,认真思考一下。
头插入的代码如下
void createhead(stunode* & head, stunode* & end) { stunode* stu = new stunode(); std::cin >> stu->name; std::cin >> stu->age; stu->next = null;if (head == null) { head = stu; end = stu; } else { stu->next = head; // 1 head = stu; // 2 } }
或许你会说,这也没啥不同呀,对的,这里面的不同就是头插入代码中的1,2行代码与尾插入中的8,9行代码不同,我用一张图来解释一下尾插入是怎么做的。
先将新建节点中的next指针指向头节点,下一步就是要移动头指针了,将头指针指向新建立的节点,这样,头插入就完成了。
其实对于尾插入和头插入,有一个结论,当采用尾插入时,遍历链表输出来的是插入的顺序,当采用头插入时,遍历链表输出的是逆序的,就是和插入顺序是相反的。
初学链表的操作可能会觉得有一点点难,不过要坚持住,不能放弃。
接下来会持续更新链表的其它操作
上一篇: 至今我都没有想明白这件事我是亏了还是赚了
下一篇: C++_类和对象