使用链表结构一次只需要一个结构体的连续空间

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
10101 “Li Lin” 18 ‘M’ 88 10102 “Zhang Fun” 19 ‘M’ 99 10104 “Wang Min” 20 ‘F’ 100
stu[0]
stu[1]
p+2
stu[2]
…...
(环节) (节点) 结构体
head
…...
…...
…...
…...
…...
0
为形成链表,结构体要增加一个成员, 即指针,指向下一个结构体节点。 如上图是一个单向链表。
优点:解决了上述两个问题
1. 需要多少结构体,就动态申请多少个结构体空间, 比数组实现节约空间。
2. 每个结点未必连续存放,通过指针将各个结点连接起来, 这样对大片连续存储区的要求降低。
3. 另外,对链表的操作如插入、删除等, 也变得比较简单了。(不需要挪动数组元素空间了)
9.10.3 链表的常用算法 ① 创建链表(有序链表、无序链表) ② 遍历链表(依次访问链表的每一个结点)
student stu[10]= { {10101, "Li Nin",18,'M',88}, {...}, {...}, ...... p+1 }; student *p; p = stu; for(i=0; i<10; i++, p++) cout << p->num << p->name << p->score << endl ;
p1
p2
NULL
输出:1000 1001 1002
[例] 链表常用算法介绍 1.创建无序链表:循环输入数据,若数值不为-1, 新建一结点并连接到链表尾部。 加入结点时, 分三种情况 ①首结点的建立 head ②中间结点的加入 ③尾结点的处理
p2 head 指向链表首结点 p2 指向建立过程中的链表尾结点 p1 指向新开辟的结点
解决:使用链表结构,一次只需要一个结构体的连续空间, 就像现实生活中的链子,由若干环节组成, 在 C++ 语言中用结构体实现链表环节,
ª 对于一个班,有多少个学生,就动态地生成多少个结构体, ª 如何来连接它们呢?用指针 ª 将它们连接成一个链表结构, 画图表示,单向链表 --->
2. 指向结构体数组元素的指针 p, stu
2019/1/6 10
2. 遍历链表
单链表的遍历:从头指针开始,顺着各个指针,依次访问链表中
的各个结点
• 关键是确定遍历的条件,即何时循环,何时终止 • 根据单链表的最后一个指针域为空 ,可以让一个工作指针指向当前 该函数是根据结点
链表及其应用
• 关于单链表掌握以下知识:
– 为什么需要单链表 – 如何通过指针和结构体的定义实现单链表结
构 – 单链表常用操作的实现Hale Waihona Puke Baidu法:建立、遍历、插 入、删除、查找、
2019/1/6
1
9.10.2 链表概念的引入
处理一个班的学生,一般使用结构体数组, 需预留足够大的数组空间 带来两个问题: 1. 多余的元素占用的空间浪费,可动态申请数组空间解决, 2. 但有时系统不能满足过大的连续存储空间的要求。
p1 程序
node *Create( ) //返回值: 链表的首指针 { node *p1, *p2, *head; int a; head = NULL; cout <<"正在创建一条无序链表...\n"; cout <<"请输入一个整数, 以 -1 结束: "; cin >> a; while( a != -1 ) // 循环输入数据,建立链表 { p1 = new node; p1->data = a; 解释 if(head==0 ) // ①建立首结点 { head=p1; p2=p1; } else // ②处理中间结点 { p2->next=p1; p2=p1; } cout <<"请输入一个整数, 以 -1 结束: "; cin >> a; } if(head != 0) p2->next=0;//③处理尾结点, 可能第1次就输入 -1 return(head); //返回创建链表的首指针
查找结点,释放链表各节点的空间
③ 删除结点
④ 插入结点
链表上的数据结点为: struct node { int data; node *next; };
[例] 动态申请,建立链表,输出各结点数据,最后循环 依次释放各结点空间。
#include <iostream.h> struct node{ int data; node *next; }; void main( ) head { node *head, *p1, *p2; head = new node; p1 = new node; p2 = new node; head->data = 1000; head->next = p1; p1->data = 1001; p1->next = p2; p2->data = 1002; p2->next = NULL; while(head!=NULL) { cout << head->data << endl; p1=head; head = head->next; delete p1; } }
结尾标志 NULL 空指针
struct student //定义节点结构体类型 { int num; /* 学号 */ char name[20]; /* 姓名 */ int age; /* 年龄 */ char sex; /* 性别 */ int score; /* 成绩 */ student *next; };
单链表的建立:
• 无论是哪一种建立方法,共同的操作是: – 最主要的是指向第一个结点的头指针,有时需要设一个指向
最后一个结点的尾指针以方便操作,注意头指针该如何修改 – 逐个申请结点空间 – 对每个结点的数据域赋值 – 每个结点的指针域如何赋值取决于建立方法 – 将新结点加入到链表中,即修改链表中某一个结点的指针域 • 后插法的关键是: – 新结点的指针域值一定为空,因为它是新的最后一个结点 – 头指针只要修改一次,即在空链状态下插入第一个点时修改 – 保证tail指针始终指在当前链表的最后一个结点处,即新结点 p插入链表之后,要做赋值: tail=p; 以后通过tail->next=p;就 可以实现在尾部插入新结点
相关文档
最新文档