1.单链表的介绍
单链表是一种线性结构,但是它不是像一维数组一样所有的存储空间都是连续的。单链表是碎片的,也就是不连续。那么它是靠什么来连接,从而使它成为一种线性结构?
如图:
L就是一个单链表的结构,a就是一个数组。
L中用红线连接起来的是一个个节点。每一个节点分为俩部分,一个是data域,还有一个是指针next域。
data域里面存放的就是数据,next存放的是下一个节点的地址,也就是这样,next一个连一个,把链表串了起来。需要注意的是:头节点,也就是第一个节点的data通常是不存储数据的。尾节点也就是最后一个节点,next是指向空的。
2.单链表的结构定义
首先是要定义一个单链表的结构
typedef struct Node{
int data; // data域,存储数据,需要存储什么类型数据,就定义什么类型
struct Node *next; // 定义指针域
} Node, *linkList;
3.单链表的初始化
初始化时,就是创建第一个节点,所以它既是头节点也是尾节点
// 初始化链表
linkList initList(){
linkList l = (linkList)malloc(sizeof(Node)); // 用malloc给链表分配空间
l->next = NULL; // 初始化时,把next指向空
return l;
}
4.单链表的建立
单链表有头插法和尾插法的建立方法
4.1头插法
// 头插法
void headInsertList(linkList list, int n){ // 传入初始化得到的链表和一个n(创建次数)作为参数
int i = 0;
while (i < n){
Node *p = (linkList)malloc(sizeof(linkList)); // 创建一个结点p
p->next = list->next; // p的next存储一开始list的next指向的地址
list->next = p; // list的next存储p的地址
scanf("%d", &p->data); .// 输入数据到data域
i++;
}
}
4.2尾插法
尾插法就是总是在链表的最后插入
// 尾插法
void endInsertList(linkList list, int n){
int i = 0;
Node *end; // 创建一个结点end
end = list; // 把list赋值给end,要操作单链表找到最后一个结点
while (i < n){
while (end->next != NULL){ // 只要next不是NULL就是说明不是最后一个
end = end->next; // 所以继续找下一个
}
Node *p = (linkList)malloc(sizeof(linkList)); // 创建一个用来插入的结点p
end->next = p; // 把一开始尾结点的next指向p
p->next = NULL; // 把p作为尾结点
scanf("%d", &p->data); // 给data赋值
i++;
}
}
4.3单链表的遍历
就是把每个节点都遍历到,这个很简单
void showList(linkList list){
Node *p;
p = list;
while (p->next != NULL){
p = p->next;
printf("%d\n", p->data);
}
}
头插法的遍历结果是逆序的,尾插法是顺序的
5.代码
最后贴上所有的代码
#include <stdio.h>
#include <stdlib.h>
typedef struct Node{
int data; // data域,存储数据,需要存储什么类型数据,就定义什么类型
struct Node *next; // 定义指针域
} Node, *linkList;
// 初始化链表
linkList initList(){
linkList l = (linkList)malloc(sizeof(Node)); // 用malloc给链表分配空间
l->next = NULL; // 初始化时,把next指向空
return l;
}
// 头插法
void headInsertList(linkList list, int n){ // 传入初始化得到的链表和一个n(创建次数)作为参数
int i = 0;
while (i < n){
Node *p = (linkList)malloc(sizeof(linkList)); // 创建一个结点p
p->next = list->next; // p的next存储一开始list的next指向的地址
list->next = p; // list的next存储p的地址
scanf("%d", &p->data); .// 输入数据到data域
i++;
}
}
// 尾插法
void endInsertList(linkList list, int n){
int i = 0;
Node *end; // 创建一个结点end
end = list; // 把list赋值给end,要操作单链表找到最后一个结点
while (i < n){
while (end->next != NULL){ // 只要next不是NULL就是说明不是最后一个
end = end->next; // 所以继续找下一个
}
Node *p = (linkList)malloc(sizeof(linkList)); // 创建一个用来插入的结点p
end->next = p; // 把一开始尾结点的next指向p
p->next = NULL; // 把p作为尾结点
scanf("%d", &p->data); // 给data赋值
i++;
}
}
void showList(linkList list){
Node *p;
p = list;
while (p->next != NULL){
p = p->next;
printf("%d\n", p->data);
}
}
int main(){
linkList l;
l = initList();
//headInsertList(l, 5);
endInsertList(l, 5);
showList(l);
return 0;
}