指针和引用
用指针处理链表
一、链表概述
链表是由一个个结点组成,每一个结点是一个结构体类型的变量,各个结点的类型相同,但其地址不一定连续。具体结点的个数根据需要动态开辟。
每个结点由两部分组成,第一部分放若干数据,第二部分是指针变量,放下一结点的地址。链表头是一指针变量,放第一个结点的地址,若结点的第二部分的值为NULL,表示此链表结束。
二、如何处理链表
1、建立链表
struct student
{ int num;
float score;
struct student *next; 指向同一结构体类型的指针变量
} ;
#define STU struct student
STU
{ int num;
float score;
STU *next; 指向同一结构体类型的指针变量
} ;
例:
struct student
{ int num;
float score;
struct student *next;
} ;
struct student *p; //定义了结构体类型的指针
p=new student; //用new开辟一结构体空间,将地址赋给p
p->num=10; //为新开辟的结构体空间中的num成员赋值
p->score=90;
1、首先定义两个结构体类型的指针 STU *p1, *p2;
2、用new在内存中开辟一个结构体变量的空间,将地址赋给p1。
p1=new student; /* STU struct student */
3、将数据赋给刚开辟的变量空间。
cin>>p1->num>>p1->score;
4、若输入的数据有效,将首地址作为链表头,head=p1; 令p2=p1,p1继续用new开辟新的内存空间。
p1=new student; /* STU struct student */
5、将下一个数据赋给新开辟的变量空间。
cin>>p1->num>>p1->score;
6、若输入的数据有效,将p2与p1连接起来,p2->next=p1 再令p2=p1,p1继续用new开辟新的内存空间。做5。若输入的数据无效,p2就是链表的尾,则p2->next=NULL。
2、输出链表
void print(STU * head)
{ STU *p;
p=head;
while(p!=NULL)
{ cout<<p->num<<‘\t’<<p->score<<‘\n’;
p=p->next; //p指向下一结点
}
}
3、删除链表
1、首先定义两个结构体类型的指针 STU *p1, *p2;
2、将链表的表头赋给p1, p1=head;
3、判断p1所指向的结点是否是要删除的结点 p1->num a1。
4、若p1->num!=a1, p2=p1; p1指向下一个结点p1=p1->next,继续判断下一个结点是否是要删除的结点。继续做3。
5、若p1->num= =a1,则p1当前指向的结点就是要删除的结点,将p2的指针成员指向p1所指的下一个结点。
这样就删除了一个结点。
特殊情况:
1、若链表为空链表,返回空指针。
2、删除的结点为头结点时,head指向下一个结点
3、链表内没有要删除的结点,返回提示信息。
4、插入结点:要插入结点的链表是排序的链表。插入10。
1、定义三个结构体指针变量 STU *p1,*p2,*p0; p0指向要插入的结点。p1=head;
2、比较p1->num 与p0->num,若p1->num<p0->num,p2=p1; p1=p1->next; 继续比较。
3、若p1->num> =p0->num,p0应插在p1与p2之间,则p2->next=p0 ; p0->next=p1;
特殊情况:
1、若链表为空链表,将插入结点作为唯一的结点,head=p0;返回。
2、若插入结点中的数据最小,则插入的结点作为头结点。
p0->next=head;
head=p0;
3、插入到链尾,插入结点为最后一个结点。
p2->next=p0;
p0->next=NULL;
用typedef定义类型
typedef定义新的类型来代替已有的类型。
typedef 已定义的类型 新的类型
typedef float REAL
REAL x, y; =====> float x, y;
1、typedef可以定义类型,但不能定义变量。
2、tyoedef只能对已经存在的类型名重新定义一个类型名,而不能创建一个新的类型名。
1、先按定义变量的方法写出定义体
2、把变量名换成新类型名
3、在前面加typedef
4、再用新类型名定义变量
typedef:编译时处理,定义一个类型替代原有的类型。