这是编程导航的算法训练营的第一期,本关主要探讨链表。
链表是一种常见的数据结构,链表中的数据不需要扎堆存储,每个节点之间使用链接的方式来寻找。
一个链表节点包含**当前值val**
和**指向下一个节点的指针next**
链表一个节点只能有一个后继,但多个节点可以指向同一个节点。
前面说过链表包含当前值和下一个节点的指针,所以每个节点都需要有这两个参数。我们把它叫做指针域和结点域。
那么我们可以用C中的结构体创建一个对象。(相当于java中的类class)
//链表结构定义
struct ListNode {
int val; //节点赋值
struct ListNode * next; //指向下一个点节点
};
定义就这么简单,那么具体如何使用呢?
下面通过创建一个链表值分别为12345的案例来说明:
使用即为将结构体创建具体的实例,我们需要先创建头结点。
那么头结点如何找到?这里就需要额外再创建一个指针指向头结点,成为头指针。这相当于大门。
//创建链表,值为12345.
struct ListNode * initLink() {
//1.创建头指针
struct ListNode * p = NULL;
//2.创建头结点
struct ListNode * temp = (struct ListNode *)malloc(sizeof(struct ListNode));
temp->val = 0;
temp->next = NULL;
//3.将指针指向头结点
p = temp;
//4.创建后面的数据,每创建一个节点用前驱结点指针指向
for(int i = 1; i < 5; i++) {
struct ListNode * a = (struct ListNode*)malloc(sizeof(struct ListNode));
a->val = i;
a->next = NULL;
//每次temp指向的节点就是a的前驱节点
temp->next = a;
//temp指向下一个节点
temp = temp->next;
}
return p;//返回完成后的链表头
}
这里创建节点时用到了C的库函数malloc
,主要作用是分配内存空间。具体用法请看https://www.runoob.com/cprogramming/c-function-malloc.html
如果要将当前链表打印输出或者进行对应的操作,这时就需要遍历。
先创建一个函数,参数为输入一个头结点。
创建一个临时节点,用于输出。循环遍历,当进行到最后一个节点的next为空或者当前节点为空则停止。
//遍历打印链表
void printList(struct ListNode * p) {
struct ListNode * temp = p; //创建临时节点用来打印输出
//如果当前节点为NULL,则退出
while(temp) {
printf("%d ", temp->val); //打印当前节点值
temp = temp->next; //跳到下一个节点
}
puts("");
}
到这里链表的基本构造就到这里,当然还有插入删除等。
接下来我们测试一下代码的正确性,当然是创建一个main函数。
int main() {
struct ListNode * p = NULL;
printf("初始化链表为: \n");
p = initLink();
printList(p); //遍历打印输出
return 0;
}