链表的概念:把若干个对象用指针串连起来,形成一个链状的数据结构,称之为“链表”。
介绍如何在C/C++中实现链表:
首先,用struct语法定义一个类型。下面例子中,以Student来存储一个学生的学号和姓名:
struct Student
{
int id;
char name[16];
Student* next;
}
注意其中添加一个成员变量next,用于指向下一个对象
链表的演示:
下面构造一个链表,用于演示各个对象“串联”起来的效果。
(1)先准备好4个对象
Student ss[4]=
{
{201501,"John",0},
{201502,"Jennifer",0},
{201503,"Anxi",0},
{201504,"Unnamed",0}
};
(2)把这4个对象“串”起来
ss[0].next=&ss[1];
ss[1].next=&ss[2];
ss[2].next=&ss[3];
ss[3].next=0;
至此,一个“链表”构造完毕!
为什么要串起来?
串起来之后,只需要知道“链表头”,就可以访问到链表中的每一个对象。
方法是:从头开始,依次访问,使用next指针来访问下一个对象
Student* p=&ss[0];
while(p)
{
printf("ID: %d, name: %s \n",p->id,p->name);
p=p->next;//下一个对象
}
这一过程,称为链表的遍历。
需要注意的是,链表中的最后一个对象的next为NULL,根据这一特征我们可以判断已经到链表的结束。
链表的特征:
链表头:指链表中的第一个对象
链表尾:指链表中的最后一个对象。他的next必须设为空指针NULL.
通常,我们用链表头来代表这个链表
Studnet* students=&ss[0];//用头部来指代整个链表
例:查找链表中的对象
查找链表中ID值为201502的对象
Studnet* find(Student* head,int id)
{
Student* p=&ss[0];
while(p)
{
if(p->id==id)//符合条件
return p;
p=p->next;
}
return NULL;//没有找到符合条件的对象
}
注:注意指针的有效性,指针指向的对象是否还“活”着。
学习过程中遇到的问题
1.为什么一个struct中的成员可以是“自己”?
struct Student
{
int id;
char name[16];
Student* next;
};
只是包含了一个指针而已,指针就是一个整数。在一个结构体中包含一个整型的成员,是再正常不过的事情。
2. 为什么最后一个对象的next必须设置为NULL?
如果不设置为NULL,那么就无法判断一个链表的结束。
小结
链表:若干对象用指针串联起来
链表的实现:必须在struct中添加一个指针作为成员,该指针指向一个对象。如果该指针为NULL,表示他是最后一个对象,他的后面就没有对象了。
链表的特征:链表头。只需要一个链表头就可以访问所有的串起来的对象。
链表尾:最后一个对象的next的值是NULL
链表的遍历:指针next来得到下一个对象
构造一个链表
#include <stdio.h>
#include <string.h>
struct Student
{
int id;
char name[16];
Student* next;
};
Student ss[4] = {
{201501, "John",0 },
{201502, "Jennifer",0 },
{201503, "AnXi",0 },
{201504, "Unnamed",0 }
};
int main()
{
ss[0].next = &ss[1];
ss[1].next = &ss[2];
ss[2].next = &ss[3];
ss[3].next = 0;
return 0;
}
按id查找链表中的对象
#include <stdio.h>
#include <string.h>
struct Student
{
int id;
char name[16];
Student* next;
};
Student* find(Student* head, int id)
{
Student* p = head;
while(p)
{
if(p->id == id) // 符合条件
return p;
p = p->next;
}
return NULL; // 没有找到符合条件的对象
}
int main()
{
// 链表的构造
ss[0].next = &ss[1];
ss[1].next = &ss[2];
ss[2].next = &ss[3];
ss[3].next = 0;
// 链表的遍历
Student* p = &ss[0];
while(p)
{
printf("ID: %d, name: %s\n", p->id, p->name);
p = p->next; // 下一个对象
}
Student* result = find(&ss[0], 201503);
return 0;
}