数组与链表的区别
1.数组
地址空间连续分配
支持随机访问
删除插入效率低
2.链表
链表当中的元素可以存在内存中的任意位置
不支持随机访问
删除与插入的效率高
3.单链表
单链表当中最后一个节点的指针域为空
信息域,地址域
该节点前一个节点,直接前驱,后一个节点,直接后继
3.1头插法创建新链表
每次让新节点作为新链表的头结点(第一个节点)
新节点放在表头,直到读入结束为止
节点顺序与插入顺序相反
虚头节点:存真正链表中的第一个节点的地址
head虚头指针:用来存放虚头节点地址
head->next = NULL;
p指针:记录每一个新节点的地址
头插法核心
p->next = head->next;
head->next = p;
3.1.1头插法代码实现
#include <stdio.h>
#include<stdlib.h>
typedef struct Nodelist {
int val;
struct Nodelist* next;
}Node;
void CreatNodeList(Node* head, int n) {
//初始化链表,链表中最后一个节点指针域为空
head->next = NULL;
Node* p;//记录每一个新节点的地址
for (int i = 1; i <= n; i++) {
p = (Node*)malloc(sizeof(Node));//申请堆区空间表示新节点
//在新节点信息域存储数据
scanf("%d", &p->val);
//新节点插入
p->next = head->next;//新节点和原链表当中第一个节点构建连接
head->next = p;//新节点与虚头节点构件连接
}
}
int main() {
Node* head = (Node*) malloc(sizeof(Node));//虚头指针用于记录虚头节点地址
//malloc申请的堆区空间,就是虚头节点,用于记录链表中真正的第一个节点的地址
int n;
scanf("%d",&n);
CreatNodeList(head, n);
head->next;
Node* s = head->next;//找到头结点位置
while (s != NULL) {
printf("%d ", s->val);
s = s->next;
}
return 0;
}
3.2尾插法创建新链表
s指针:每次用于记录最后一个节点的地址
p->next=NULL;
s->next=p;
s=p;
3.2.1尾插法代码实现
#include <stdio.h>
#include<stdlib.h>
typedef struct NodeList {
int val;
struct NodeList* next;
}Node;
void CreatList(Node* head, int n) {
head->next = NULL;
Node* s = head;
Node* p;
for (int i = 1; i <= n; i++) {
p = (Node*)malloc(sizeof(Node));
scanf("%d", &p->val);
p->next = NULL;
s->next = p;
s = p;
}
}
int main() {
Node* head = (Node*)malloc(sizeof(Node));
int n;
scanf("%d", &n);
CreatList(head, n);
Node* t = head->next;
while (t != NULL) {
printf("%d ", t->val);
t = t->next;
}
return 0;
}