目录
链表的概念
链表的组成:
基本概念:
链表的种类
建立一个静态链表
动态链表
如何动态的生成一个链表?
1.函数原型: void *malloc(unsigned size)
2.函数原型: void free(void*p)
3.几点注意:
特点:
建立单链表
关于单链表
建立单链表的主要步骤:
代码
链表是动态地进行存储分配的一种结构,链表中的数据在内存中不必连续存放,数据之间通过指针链接起来,相比于数组结构,链表的插入和删除操作比较方便。
如图,随机开辟5个空间,第一个空间称为链表的表头,它存放第二个空间的地址。剩下的每块空间分为数据域和指针域。数据域用来存放数据,指针域存放下一块空间的地址,从而将每块空间链接起来。最后一块空间称为链表的表尾,其指针域存放一个空指针,用于结束链表。
①链表指的是将若干个数据项按一定的规则连接起来的表。
②链表中的数据项称为结点。
③链表中每一个结点的数据类型都包含一个自引用结构
④自引用结构就是结构成员中包含一一个指针成员,该指针指向与自身同一个类型的结构。
因此:链表就是结构体变量与结构体变量连接在一起。(通过结 构体指针)
例如:
struct node
{
int data;
struct node*next;
};
struct student
{
int num;
char name[10];
int age;
}
struct node
{
struct node stu;
struct node*next;
};
解析:链表中的结点是结构体类型的数据,每个结点的所有成员分为两部分,一部分用来存放数据(各种实际的信息),如编号、姓名和年龄等;另一部分存放指针,用来连接其它结点。
struct node
{
int data;
struct node*next;
};
int main()
{
struct node n1={1,NULL};
struct node n2={2,NULL};
struct node n3={3,NULL};
struct node*p;
n1.next=&n2;
n2.next=&n3;
p=&n1;
while(p!=NULL)
{
printf("%d\t",p->data);
p=p->next;
}
return 0;
}
此例用于说明链表的构成,静态链表作用不大,一般使用动态链表
指动态的数据结构,可以将不连续的内存数据连接起来。用上malloc、free函数
需要用到的几个函数和运算符:
malloc()和free()函数以及sizeof运算符的配合使用
(注: malloc()和free()函 数在头文件stdlib.h或alloc.h)。
功能:从内存分配-一个大小为size个字节的内存空间。.
◆若成功,返回新分配内存的首地址;若没有足够的内存分配,则返回NULL。
◆通常函数malice()通常和运算符sizeof一起使 用。
例如:
int * p;
p= (int *) malloc(20*sizeof(int)); / *分配20个整型数所需的内存空间* /
系统分配能存放20个整型数连续空间,p指向该存储空间的首地址。
例如:
struct student
{ int no;
int score;
struct student *next;
};
struct student*stu;
stu=malloc(sizeof(struct student));
功能:释放由malloc函数所分配的内存块,无返回值。例如: free(stu);
作用:将stu所指的内存空间释放。
①结构类型占用的内存空间不一定是连续的,因此,应该用sizeof运算符来确定结构类型占用内存空间的大小。
②使用malloc()函数时,应对其返回值进行检测是否为NULL,以确保程序的正确。
③要及时地使用free()函数释放不再需要的内存空间,避免系统资源过早地用光。
④不要引用已经释放的内存空间。
1、链表中的每一个结点是在需要的时候建立的。
2、各结点在内存中的存储地址不一定是连续的,由系统自动分配的,即有可能是连续分配内存空间,也有可能是跳跃式的不连续分配内存空间。
单链表的建立链表:通过自引用结构的指针域,将各结点相互连接。关于链表的基本概念:
(1)链表的第一个结点称头指针或头结点,它指向链表在内存中的首地址,
(2)其后的结点是通过结点中的链节指针成员访问的。
(3)链表的最后一个结点称为尾节点。尾节点的指针域通常被设置成NULL。
(4)链表中的每一个结点是在需要的时候建立的。
(5)各结点在内存中的存储地址不一定是连续的,由系统自动分配的,即有可能是连续分配内存空间,也有可能是跳跃式的不连续分配内存空间。
①定义单链表的数据结构(定义自引用结构)
②建立表头(建立一个空表)。
③创建一个结点
④插入一个结点(表头、表尾、指定位置插入)
⑤删除结点(指定删除)
⑥遍历链表(打印输出值)
1、定义单链表的数据结构
struct Node {
int data;
struct Node* next;
};
2、建立表头
struct Node* creatlist()
{
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->next = NULL;
return head;
}
3、创建一个结点
struct Node* creatnode(int data)
{
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
4、插入一个结点(这里我们使用在表头插入的方法)
void InsertNode(struct Node* head, int data)
{
struct Node* newnode = creatnode(data);
newnode->next = head ->next;
head->next = newnode;
}
head->next即图中newnode1的地址,将其赋给newnode2->next。再将head->next修改成newnode2的地址。这样就将新结点插入进去。这里特别注意顺序
5、删除结点
void deleteNode(struct Node* head, int givedata)//head为表头,givedata为要删除的数据
{
struct Node* giveNode = head->next;//giveNode为表头的下一个结点
struct Node* frontgiven = head;
if (giveNode == NULL)
{
printf("链表为空");
}
else
{
while (giveNode->data != givedata)//匹配数据域,不同则后移
{
frontgiven = giveNode;
giveNode = giveNode->next;
if (giveNode == NULL)
{
printf("找不到该数据");
break;
}
}
frontgiven->next = giveNode->next;//找到要删除的数据,将前一个结点的指针域指向下一个结点
free(giveNode);
}
}
6、遍历链表
void print(struct Node*head)
{
struct Node* p=head->next;
while (p)
{
printf("%d\t", p->data);
p = p->next;
}
}
7、全部代码:
#include
#include"stdlib.h"
struct Node {
int data;
struct Node* next;
};
struct Node* creatlist()
{
struct Node* head = (struct Node*)malloc(sizeof(struct Node));
head->next = NULL;
return head;
}
struct Node* creatnode(int data)//创建一个结点
{
struct Node* newnode = (struct Node*)malloc(sizeof(struct Node));
newnode->data = data;
newnode->next = NULL;
return newnode;
}
void InsertNode(struct Node* head, int data)
{
struct Node* newnode = creatnode(data);
newnode->next = head ->next;
head->next = newnode;
}
void print(struct Node*head)
{
struct Node* p=head->next;
while (p)
{
printf("%d\t", p->data);
p = p->next;
}
}
void deleteNode(struct Node* head, int givedata)
{
struct Node* giveNode = head->next;
struct Node* frontgiven = head;
if (giveNode == NULL)
{
printf("链表为空");
}
else
{
while (giveNode->data != givedata)
{
frontgiven = giveNode;
giveNode = giveNode->next;
if (giveNode == NULL)
{
printf("找不到该数据");
break;
}
}
frontgiven->next = giveNode->next;
free(giveNode);
}
}
int main()
{
//建立一个表头
struct Node* list = creatlist();
/*int xuehao;*/
/*int flag = 1;*/
//while (flag) {
// printf("请输入一个学号\n");
// scanf("%d", &xuehao);
// //在表头插入数据
// InsertNode(list, xuehao);
// printf("是否继续输入信息,请选择:0:否、1:是\n");
// scanf("%d", &flag);
//}
InsertNode(list, 1);
InsertNode(list,2);
InsertNode(list, 3);
//打印链表
print(list);
printf("\n");
//删除一个数据
deleteNode(list, 3);
print(list);
return 0;
}