数据结构之线性表-头插法创建单链表-学习笔记-14

引入

我们知道如何查找、插入、删除一个数据元素,那么在最初该如何创建一个单链表呢?单链表的效率真的比顺序表高嘛?高在哪里呢?

整表创建对比

顺序表的整表创建:可以用数组的初始化来理解,因为数组就是最常见的顺序表。
单链表的整表创建:单链表就跟顺序表有很大不同。

  • 单链表的数据没有顺序存储结构这么集中。
  • 数据可以是分散在内存各个角落
  • 数据增长是动态进行的
  • 每个链表的大小和位置不需要预先分配
  • 根据系统情况和实际需求即时生成
  • 总结就是灵活多变!

单链表的整表创建

首先要明确思路,单链表是动态生成的,从空表开始,依次建立元素结点,并且插入链表中。所以,大致的算法思路如下:

  • 声明一个节点 P 和 计数器变量 i
  • 初始化一个空链表 L
  • 让 L 的头结点指向 NULL,建立一个带有头结点的单链表
  • 通过循环插入后继结点

头插法创建单链表

头插法是一种创建单链表的方式

  • 从一个空表开始
  • 生成新结点,读取数据放到新节点的数据域中
  • 将新结点将新节点插入到当前链表的表头,直到结束

简单来说就是从头部开始插入,放在头部后面的第一个位置

  • 新节点的 next 指向头结点
  • 表头指向新节点

注意顺序
因为是头插法,先来的在链表后面,后来的在链表前面,记得不要搞错!

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include <stdio.h>
#include <stdlib.h>
#define LEN sizeof(struct Student)
struct Student{
int num;
char name[20];
float score;
struct Student *next;
};

struct Student *create(void){
struct Student *a,*head;
head=(struct Student *)malloc(LEN);
a=(struct Student *)malloc(LEN);
printf("请输入学生信息:\n");
scanf("%d %s %f",&a->num,a->name,&a->score);
head->next=NULL;
while(a->num!=0){
a->next=head->next;
head->next=a;
a=(struct Student *)malloc(LEN);
scanf("%d %s %f",&a->num,a->name,&a->score);
}
return head;
}

void print(struct Student * p){
p=p->next;
while(p!=NULL){
printf("%d号%s的成绩是:%3.1f\n",p->num,p->name,p->score);
p=p->next;
}
}

int main(){
struct Student* stu_p;
stu_p=create();
print(stu_p);
return 0;
}

输出结果
请输入学生信息:
10001 liulin 99
10002 lin 99.9
10003 bliner 100
0 0 0
10003号bliner的成绩是:100.0
10002号lin的成绩是:99.9
10001号liulin的成绩是:99.0

其实最关键的就是中间循环的那几句

  • 头部创建动态存储空间,指向 NULL
  • 新的指向头部指向的 Next
  • 头部指向新的
  • 这样就插到了头部后面的第一个

头部和头结点
头部:数据域一般为空,指针域指向头结点。
头结点:链表的第一个结点称为头结点,头部指向头结点

伪代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <time.h>
#define ERROR 0
#define OK 1
typedef int Elemtype
struct Node{
Elemtype data;
struct Node * next;
};
//构建单链表
typedef struct Node* LinkList;

void CreateListHead(LinkList *L , int n){
LinkList *p;
int i;
srand((time(0))); //设置随机数种子

L=(LinkList *)malloc(sizeof(Node));
(*L)->next=NULL;

for( i=0; i<n; i++){
p = (LinkList *)malloc(sizeof(Node)); //产生新结点
p->data =rand()%100+1; //随机数取余100,就是100以内的随机数
p->next=L->next; //新结点的 next 指向头部的 next
L->next=p; //头部的 next 指向新结点
}
}

尾巴

这是我的个人学习笔记,主要是应付考研复习使用,充斥着一些吐槽和个人观点,并不严谨,欢迎大家参考、指正。


-------------The End-------------
欢迎请我喝咖啡哦~!