实现你的第一个链表——手把手教你创建单向链表
Posted mzzx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了实现你的第一个链表——手把手教你创建单向链表相关的知识,希望对你有一定的参考价值。
写在前面
这是我原发在独立博客上的文章,用来帮助初学链表的同学们理解链表,现在发在这里供大家批评。
为什么要使用链表?
这是我们首先要考虑的一个问题,我们之前已经学过了数组的使用,可以方便快速地存储大量数据,为何还要引入“链表”的概念呢?
比如我们让50个小朋友排排坐,那事情是很好办的:只需要准备50个椅子,让小朋友们依次坐好即可,这就是数组的使用。但是,如果我们预先不知道有多少小朋友,那事情就不好办了,我们可能需要准备大量的椅子,但这就会浪费很多空间;此外,如果一个新来的小朋友必须进入特定两人之间,椅子是静态的,只能让后面的人一个一个依次往后挪,他才能坐到这个位置,这无疑十分浪费时间。
因此,在这种情况下,我们不再让小朋友排排坐,而是让每人拉着另一个人的衣襟,这样不需要确定椅子数,如果有人需要插入,也只需改变一两个人拉谁的衣襟即可。这也就是我们所说的链表。(要注意,这里是“拉衣襟”而不是“手拉手”,因此严格地说是一种单向链表)
C语言实现
实现方式的选择
我们现在已经知道,要实现链表,我们需要有数据(小朋友),又要把数据连起来(拉衣襟),在编程中,我们特别需要考虑对“拉衣襟”的实现,这时,C语言中的指针就为我们提供了绝佳的工具,因为它可以指向其他的元素。为了将数据和指针组合起来,我们需要一个结构体,在链表中,我们将这种数据域和指针域的组合称为结点(node)。
在这里的例子中,为了简单,我们在每个结点只存储一个整型变量:
typedef struct linked_list {
int num;
struct linked_list* next;
} l;
在这个结点中,数据域为整型变量num,指针域为指针next,用来指向下一个结点,结点之间依次相连,从而实现“拉衣襟”的操作。
创建结点
创建头结点
很多时候,我们都需要先创建一个不存储数据的头结点,这样即使遇到空链表或对第一个元素的操作等情况也不会出现问题。(注:在课本示例中,并没有使用头结点,但我认为最好使用)
特别注意下面几个名词的区别!
- 头结点:一个空结点,位于单向链表最前面,它的指针域指向第一个有数据的结点
- 尾结点:最后一个结点,它的指针域最终指向NULL
- 头指针:指向头结点的指针,在访问单向链表时要从这个指针所指的结点开始
- 尾指针:指向尾结点的指针,用于创建链表过程中的操作
l * head, * new_node, * tail; //声明头指针、创建新结点所用指针、尾指针
head = (l*)malloc(sizeof(l)); //为头结点分配内存
tail = head; //让尾指针指向头指针
创建数据结点
接下来我们就可以创建有数据的结点内容了!下面先以其中一个结点为例:
new_node = (l*)malloc(sizeof(l)); //为结点分配内存
scanf("%d", &new_node->num); //输入数据
tail->next = new_node; //让尾结点的指针域指向新创建的结点
tail = new_node; //让尾指针指向新的结点
当然,在实际中,肯定不会只创建一个数据结点,而是用循环语句创建完所需的所有结点。
结束链表创建
现在,我们假设所有结点创建完毕,需要进行最后一步——将尾结点的指针域指向NULL,这样就可以标记链表的结束。
tail->next = NULL;
创建链表的整体操作
#include<cstdio>
#include<cstdlib>
//使用结构体构建结点
typedef struct linked_list {
int num;
struct linked_list* next;
} l;
l* create(int n) {
l * head, * new_node, * tail;
int i = 0;
//创建头结点
head = (l*)malloc(sizeof(l));
tail = head;
//使用循环,创建n个数据结点
for(i=0; i<n; ++i) {
new_node = (l*)malloc(sizeof(l));
scanf("%d", &new_node->num);
tail->next = new_node;
tail = new_node;
}
//将尾结点的指针域指向NULL,标志链表结束
tail->next = NULL;
//返回头指针
return head;
}
int main() {
l* head_pointer;
int n;
printf("请输入数据个数:");
scanf("%d", &n);
printf("请依次输入数据:");
head_pointer = create(n);
/*
下面可以进行链表操作,本文暂不演示
*/
return 0;
}
要注意,我们需要在最后让函数返回头指针,以便在主函数中通过头指针访问我们所创建的链表。
总结
本文一步步介绍了创建一个链表的方法,由于我写了半天,现在有点犯懒了,欲知链表的访问、修改等操作,且听下回分解……
以上是关于实现你的第一个链表——手把手教你创建单向链表的主要内容,如果未能解决你的问题,请参考以下文章