复习与补充二
1、结构体类型的定义与结构体变量
2、结构体指针
3、自定义数据类型
4、链表的概念与形成链表的基本要素
5、链表的操作:创建、插入、删除结构体类型与链表
1,结构体类型的定义与结构体变量结构体类型是一种构造性类型,可以将不同类型的数据项作为一个整体来操作,且数据项可以是不同的数据类型,可以是基本数据类型,也可以是构造数据类型。
格式定义格式,struct 结构体名 {
数据类型 1 数据项标识 1;
数据类型 2 数据项标识 2;
……
};
例:
struct person
{ char name[20];
int age;
char sex;
long num;
char address[20];
};
struct person p1;
定义结构体类型变量的方法定义结构体变量有几种方法
1、先定义结构体类型,再定义结构体变量;
struct s {int a; float f};
struct s x,y;
2、同时定义结构体类型和变量;
struct s {int a;float f}x,y;
3、不指定结构体类型名,直接定义变量;
struct
{int a;float f}x,y;
注意,1、定义变量才能分配相应内存空间,类型只是说明一种格式;
2、结构体类型可以嵌套定义例,b2_struct
结构体变量的引用引用是对结构体变量中的成员进行访问,其格式是:
结构体变量名? 成员名对嵌套定义的结构体类型进行多层引用。
如,struct date{int year; int month; int day};
struct student{char name[20];
struct date birthday;
}stu1;
则引用,stu1.birthday.year
成员的引用可以进行成员类型相关的运算。
相同类型的结构体变量可以相互赋值。
2、结构体指针结构体变量的首地址称为结构体变量的指针,该地址可以赋值给一个指针变量。
一、结构体指针变量的定义
struct s{int x,y;
float z;};
struct s a,*p; a为结构体变量,p为指针变量二、通过结构体指针变量对结构体成员操作若有以上定义,且有赋值语句,p=&a; 则指针 p指向结构体变量 a。
a.x (*p).x 注意括号 p->x 三种形式均对结构体变量 a取成员。
例,struct_pointer
3、自定义数据类型调用函数时传递数组地址
1、简单的名字替换; typedef int INTEGER;
将 int型定义为 INTEGER,则 INTEGER a;相当于 int a;
2、定义一个类型名代表一个结构体类型;
typedef struct 则 STUDENT为一个结构体类型名,
{ char name[20]; 可以直接用来定义变量,如:
long num; STUDENT student1,student2;
float score;
}STUGENT;
3、定义数组,typedef int COUNT[20];
COUNT a,b; a,b为 20元素的整型数组
4、定义指针,typedef char *STRING;
STRING p1,p2; p1,p2为字符类型指针
4、链表的概念与形成链表的条件
定义是一种有序的列表。链表的内容通常是存储于内存中分散的位置上。
链表的两种形式一种是利用数组结构串连的有序列表,称静态链表;另一种以动态内存配置的链表,称动态链表,简称链表。
形成链表的基本要素:
(1) 元素节点。由一个包含指针成员的结构体组成;
(2) 结点中的指针成员保留其后继结点的地址信息。
2010
2010
2011 x
2018
2018
2019 x
4048
4048
4049 x
NULL
p
头指针结点 1 结点 2 结点 3
指针成员要形成链表,需要用结构体数据类型,在结构体类型中需要有一个指向本类型的指针成员,以便指向下一个结构体变量。
例,struct stud_score
{ int x;
struct stud_score *next;
};
以上三个结构体变量在内存中的地址并不是连续的,但通过链表关联起来。
1
2
3
4
5
6
7
8
9
01
张三李四刘六王五
3
0
- 1
4P
静态链表
Struct student
{
char name[10];
int next;
}S[10];
张三 李四 王五 刘六
5、链表的操作
链表的创建创建动态链表从一个空指针 H开始,每增加一个元素时首先通过动态存储分配创建一个结点(获得存储空间),将元素值赋值到结点的数据域,如果是第一个结点( H==NULL),
则将该结点的地址赋值给上述指针,且将该结点的指针域赋值 NULL,表示该结点没有后继结点;如果不是第一个结点,则将结点插入已有的链表中。
定义结构体类型:
struct node
{
int data;
struct node *next;
}
struct node *head,*p;
head = NULL;
int d;
scanf(“%d”,&d);
while(d != -1)
{
p = (struct node *)malloc(sizeof(struct node));
p->data = d;
if(h == NULL)
{
h = p; p->next = NULL;
}
else
{
p->next = h; h = p;
}
scanf(“%d”,&d”);
}
头插法创建链表
NULLh 结点地址p 数据data
NULLnext
数据结点地址数据
NULL
结点地址h
结点地址p 数据
NULL
p->next = h; 数据结点地址数据
NULL
结点地址h
结点地址p 数据结点地址
h = p;
数据结点地址数据
NULL
结点地址h
结点地址p 数据结点地址结点地址h
结点地址p
数据data
NULLnext
h = p;
定义结构体类型:
struct node
{
int data;
struct node *next;
}
struct node *head,*p,*t;
head = NULL;
int d;
scanf(“%d”,&d);
while(d != -1)
{
p = (struct node *)malloc(sizeof(struct node));
p->data = d;
if(h == NULL)
{
h = p; p->next = NULL,t = p;
}
else
{
t->next = p; p->next = NULL; t = p;
}
scanf(“%d”,&d”);
}
尾插法创建链表
NULLh 结点地址p 数据data
NULLnext
数据结点地址数据
NULL
结点地址h
结点地址p 数据
NULL
t->next = p; 数据结点地址数据结点地址结点地址h
结点地址p
数据
NULL
p-> = NULL;
t = p;
结点地址h
结点地址p
数据data
NULLnext
h = p;
t = p;
NULLt 结点地址t
结点地址t
结点地址t
数据结点地址数据结点地址结点地址h
结点地址p
数据
NULL
结点地址t
结点插入要在链表中插入一个节点,首先要创建该节点,然后用一个指针从链表头开始找到要插入位置的前一节点。
数据结点地址数据结点地址结点地址h 数据
NULL
结点地址q
插入位置 N=2
数据随机值结点地址p
q = h;
i = 1;
while(i < N-1)
{
q = q->next;
i++;
}
p->next = q->next;
q->next = p;
插入位置可以为从起始位置起第 N个,也可以通过数据比较。
结点删除通过指针 q找到要删除结点的前一结点。再用另一指针 p
指向要删除的结点。
数据结点地址数据结点地址结点地址h 数据
NULL
要删除的结点 N=2
结点地址q
q = h;
i = 1;
while(i < N-1)
{
q = q->next;
i++;
}
结点地址p
p = q->next;
q->next = p->next;
free(p);
对删除 N=1的结点要特殊处理作业
1,P49 2.3
注意,P,S,Q,L均是结点结构体类型的指针。
1、结构体类型的定义与结构体变量
2、结构体指针
3、自定义数据类型
4、链表的概念与形成链表的基本要素
5、链表的操作:创建、插入、删除结构体类型与链表
1,结构体类型的定义与结构体变量结构体类型是一种构造性类型,可以将不同类型的数据项作为一个整体来操作,且数据项可以是不同的数据类型,可以是基本数据类型,也可以是构造数据类型。
格式定义格式,struct 结构体名 {
数据类型 1 数据项标识 1;
数据类型 2 数据项标识 2;
……
};
例:
struct person
{ char name[20];
int age;
char sex;
long num;
char address[20];
};
struct person p1;
定义结构体类型变量的方法定义结构体变量有几种方法
1、先定义结构体类型,再定义结构体变量;
struct s {int a; float f};
struct s x,y;
2、同时定义结构体类型和变量;
struct s {int a;float f}x,y;
3、不指定结构体类型名,直接定义变量;
struct
{int a;float f}x,y;
注意,1、定义变量才能分配相应内存空间,类型只是说明一种格式;
2、结构体类型可以嵌套定义例,b2_struct
结构体变量的引用引用是对结构体变量中的成员进行访问,其格式是:
结构体变量名? 成员名对嵌套定义的结构体类型进行多层引用。
如,struct date{int year; int month; int day};
struct student{char name[20];
struct date birthday;
}stu1;
则引用,stu1.birthday.year
成员的引用可以进行成员类型相关的运算。
相同类型的结构体变量可以相互赋值。
2、结构体指针结构体变量的首地址称为结构体变量的指针,该地址可以赋值给一个指针变量。
一、结构体指针变量的定义
struct s{int x,y;
float z;};
struct s a,*p; a为结构体变量,p为指针变量二、通过结构体指针变量对结构体成员操作若有以上定义,且有赋值语句,p=&a; 则指针 p指向结构体变量 a。
a.x (*p).x 注意括号 p->x 三种形式均对结构体变量 a取成员。
例,struct_pointer
3、自定义数据类型调用函数时传递数组地址
1、简单的名字替换; typedef int INTEGER;
将 int型定义为 INTEGER,则 INTEGER a;相当于 int a;
2、定义一个类型名代表一个结构体类型;
typedef struct 则 STUDENT为一个结构体类型名,
{ char name[20]; 可以直接用来定义变量,如:
long num; STUDENT student1,student2;
float score;
}STUGENT;
3、定义数组,typedef int COUNT[20];
COUNT a,b; a,b为 20元素的整型数组
4、定义指针,typedef char *STRING;
STRING p1,p2; p1,p2为字符类型指针
4、链表的概念与形成链表的条件
定义是一种有序的列表。链表的内容通常是存储于内存中分散的位置上。
链表的两种形式一种是利用数组结构串连的有序列表,称静态链表;另一种以动态内存配置的链表,称动态链表,简称链表。
形成链表的基本要素:
(1) 元素节点。由一个包含指针成员的结构体组成;
(2) 结点中的指针成员保留其后继结点的地址信息。
2010
2010
2011 x
2018
2018
2019 x
4048
4048
4049 x
NULL
p
头指针结点 1 结点 2 结点 3
指针成员要形成链表,需要用结构体数据类型,在结构体类型中需要有一个指向本类型的指针成员,以便指向下一个结构体变量。
例,struct stud_score
{ int x;
struct stud_score *next;
};
以上三个结构体变量在内存中的地址并不是连续的,但通过链表关联起来。
1
2
3
4
5
6
7
8
9
01
张三李四刘六王五
3
0
- 1
4P
静态链表
Struct student
{
char name[10];
int next;
}S[10];
张三 李四 王五 刘六
5、链表的操作
链表的创建创建动态链表从一个空指针 H开始,每增加一个元素时首先通过动态存储分配创建一个结点(获得存储空间),将元素值赋值到结点的数据域,如果是第一个结点( H==NULL),
则将该结点的地址赋值给上述指针,且将该结点的指针域赋值 NULL,表示该结点没有后继结点;如果不是第一个结点,则将结点插入已有的链表中。
定义结构体类型:
struct node
{
int data;
struct node *next;
}
struct node *head,*p;
head = NULL;
int d;
scanf(“%d”,&d);
while(d != -1)
{
p = (struct node *)malloc(sizeof(struct node));
p->data = d;
if(h == NULL)
{
h = p; p->next = NULL;
}
else
{
p->next = h; h = p;
}
scanf(“%d”,&d”);
}
头插法创建链表
NULLh 结点地址p 数据data
NULLnext
数据结点地址数据
NULL
结点地址h
结点地址p 数据
NULL
p->next = h; 数据结点地址数据
NULL
结点地址h
结点地址p 数据结点地址
h = p;
数据结点地址数据
NULL
结点地址h
结点地址p 数据结点地址结点地址h
结点地址p
数据data
NULLnext
h = p;
定义结构体类型:
struct node
{
int data;
struct node *next;
}
struct node *head,*p,*t;
head = NULL;
int d;
scanf(“%d”,&d);
while(d != -1)
{
p = (struct node *)malloc(sizeof(struct node));
p->data = d;
if(h == NULL)
{
h = p; p->next = NULL,t = p;
}
else
{
t->next = p; p->next = NULL; t = p;
}
scanf(“%d”,&d”);
}
尾插法创建链表
NULLh 结点地址p 数据data
NULLnext
数据结点地址数据
NULL
结点地址h
结点地址p 数据
NULL
t->next = p; 数据结点地址数据结点地址结点地址h
结点地址p
数据
NULL
p-> = NULL;
t = p;
结点地址h
结点地址p
数据data
NULLnext
h = p;
t = p;
NULLt 结点地址t
结点地址t
结点地址t
数据结点地址数据结点地址结点地址h
结点地址p
数据
NULL
结点地址t
结点插入要在链表中插入一个节点,首先要创建该节点,然后用一个指针从链表头开始找到要插入位置的前一节点。
数据结点地址数据结点地址结点地址h 数据
NULL
结点地址q
插入位置 N=2
数据随机值结点地址p
q = h;
i = 1;
while(i < N-1)
{
q = q->next;
i++;
}
p->next = q->next;
q->next = p;
插入位置可以为从起始位置起第 N个,也可以通过数据比较。
结点删除通过指针 q找到要删除结点的前一结点。再用另一指针 p
指向要删除的结点。
数据结点地址数据结点地址结点地址h 数据
NULL
要删除的结点 N=2
结点地址q
q = h;
i = 1;
while(i < N-1)
{
q = q->next;
i++;
}
结点地址p
p = q->next;
q->next = p->next;
free(p);
对删除 N=1的结点要特殊处理作业
1,P49 2.3
注意,P,S,Q,L均是结点结构体类型的指针。