七 、结构体与链表(三)

19
七七七 七七七七 七七 、体() 七七七 七七七七 七七 、体() 7.1 7.1 结结 结结 结结 结结 7.2 7.2 结结 结结结结 结结 结结结结 7.3 7.3 结结 结结结结结结 结结结 结结结 体、、 结结 结结结结结结 结结结 结结结 体、、 7.4 7.4 结结 结结结结结结 结结 结结结结结结 7.5 7.5 结结 结结 结结 结结 7.6 7.6 结结结结 结结结结 7.7 7.7 结结结结结结结 结结结结结结结

description

七 、结构体与链表(三). 7.1 结构体概述 7.2 结构体类型声明 7.3 结构体变量的定义、使用、初始化 7.4 结构体数组及其应用 7.5 结构体指针 7.6 链表概述 7.7 创建和操作链表. 7.5 结构体指针. 1 、 概述 一个指针变量用来指向一个结构变量时,称为结构指针变量。结构指针变量中的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量。 2 、 指向结构变量的指针的定义 struct 结构体名 *结构指针变量名 struct Stud { int sno; char sname[20]; - PowerPoint PPT Presentation

Transcript of 七 、结构体与链表(三)

Page 1: 七 、结构体与链表(三)

七 、结构体与链表(三)七 、结构体与链表(三)7.1 7.1 结构体概述结构体概述7.2 7.2 结构体类型声明结构体类型声明7.3 7.3 结构体变量的定义、使用、初始化结构体变量的定义、使用、初始化7.4 7.4 结构体数组及其应用结构体数组及其应用7.5 7.5 结构体指针结构体指针7.6 7.6 链表概述链表概述7.7 7.7 创建和操作链表创建和操作链表

Page 2: 七 、结构体与链表(三)

7.5 7.5 结构体指针结构体指针11 、、概述 一个指针变量用来指向一个结构变量时,称为结构指针变一个指针变量用来指向一个结构变量时,称为结构指针变

量。结构指针变量中的值是所指向的结构变量的首地址。量。结构指针变量中的值是所指向的结构变量的首地址。通过结构指针即可访问该结构变量。通过结构指针即可访问该结构变量。

2 、指向结构变量的指针的定义指向结构变量的指针的定义 struct struct 结构体名 结构体名 ** 结构指针变量名结构指针变量名 struct Studstruct Stud {{

int sno;int sno; char sname[20];char sname[20]; float score;float score; } stu;} stu; struct Stud *pstruct Stud *p= &stu; &stu;

Page 3: 七 、结构体与链表(三)

3 、访问结构成员变量的三种方法( 1 ) stu.sno 、 stu.sname 、 stu.score( 2 ) (*p).sno 、 (*p).sname 、 (*p).score ( 3 ) p->sno 、 p->sname 、 p->score

4 、说明( 1 ) “ -> ”为指向运算符,是优先级最高的运算符;( 2 ) 采用“ (*p). 成员名 ” 形式时,括号不能省略;( 3 )经常这样使用: p->num 、 p->num++ 、 ++ p-

>num

// 这种使用方法一定要习惯

Page 4: 七 、结构体与链表(三)

5 、指向结构数组的指针 struct st

{

int sno;

char sname[20];

float score;

} stu[29], *p;

合法的操作: p=stu;p=&stu[3];

p+1 、 (++p)->num 、 ++p->num 、 (p++)->num 、 p->num++ 等

Page 5: 七 、结构体与链表(三)

6 、用结构体变量和指向结构体的指针作函数参数

( 1 )用结构体变量的成员作实参(传值) void fun(int); // 函数声明

fun(stu.sno); // 函数调用

( 2 )用结构体变量作实参(传值) 要求形参也必须是同类型的结构体变量。

( 3 )用指向结构体变量 ( 或数组 ) 的指针作实参 将结构体变量 ( 或数组 ) 的首地址传给形参

Page 6: 七 、结构体与链表(三)

7.6 7.6 链表概述链表概述 一种常用的、能够实现动态存储分配的数据结构。 链表:若干数据按一定原则连接起来的表。链表的前一

结点指向后一结点,只能通过前一结点才能找到后一结点。第一个结点没有前趋,最后一个结点没有后继。链表必须有链表结束标志,最后一个结点的指针域的值为NULL 。单链表必须从头开始(通常有一个头指针)顺序访问;而不可随机访问。

结构体可以嵌套声明,而结构成员不能是自身的结构变量,但可以用结构体指针作为成员。

结点:链表的每个结构体变量是一个结点。 链表是动态存储分配的数据结构。 链表有单向链表、双向链表、循环链表等形式(此处只

讨论单向链表)。

Page 7: 七 、结构体与链表(三)

7.7 7.7 创建和操作链表创建和操作链表

7.7.1 7.7.1 链表结构链表结构7.7.2 7.7.2 创建单链表创建单链表7.7.3 7.7.3 遍历单链表(遍历单链表(从头开始,顺序输出)7.7.4 7.7.4 查找查找7.7.5 7.7.5 插入操作插入操作7.7.6 7.7.6 删除操作删除操作

Page 8: 七 、结构体与链表(三)

7.7.1 链表结构

链表是一种常见且重要的数据结构。它是动态地进行存储分配的一种结构。

因数组存放数据时,必须事先定义固定的长度。若事先难以确定数组的大小,则必须把数组定得足够大,显然这将会浪费内存。而链表则没有这种缺点,它根据需要开辟内存单元。(也可使用指针的堆内存分配来解决这个问题)

若对数组元素进行插入和删除操作,执行效率非常低下,对于经常对元素进行插入和删除操作的情况,采用链表无疑将是你的首选。

Page 9: 七 、结构体与链表(三)
Page 10: 七 、结构体与链表(三)

链表有一个“头指针”变量,前图中以 head表示,它存放一个地址,该地址指向第一个元素。链表中的元素常称为结点,每个结点都应包括两个部分:一为用户需要用的实际数据,二为下一个结点的地址。 head指向第一个元素;第一个元素又指向第二个元素……直到最后一个元素,该元素不再指向其他元素,它称为“表尾”,它的地址部分为空值( NULL),链表到此结束。

链表中各元素在内存中一般不是连续存放的。要找某一元素,必须先找到上一个元素,根据它提供的下一元素地址才能找到下一个元素。如果不提供“链表头” (head),则整个链表都无法访问。链表如同一条铁链一样,一环扣一环,中间是不能断开的。链表的这种数据结构,必须利用指针变量才能实现。即:一个结点中应包含一个指针变量,用它存放下一结点的地址。

Page 11: 七 、结构体与链表(三)

7.7.2 创建单链表设链表的结点结构为:struct Node{

int data;  struct Node *next;};建立链表的两种的思想: ( 1 )新结点链到表尾 ( 2 )新结点链到表头

while(true)while(true)

{{

int d;int d;

cin>>d;cin>>d;

if(d == 0) break;if(d == 0) break;

q=new Node; q=new Node; // step 1// step 1

q->data=d;q->data=d; // 2// 2

q->next=NULL; // 3q->next=NULL; // 3

p->next=q;p->next=q; // 4// 4

p=q;p=q; // 5// 5

}}

return head;return head;

}}

int main()int main()

{{

Node *h= CreateByTail();Node *h= CreateByTail();

return 0;return 0;

}}

// // 新结点链到表尾新结点链到表尾struct Node *CreateByTail() struct Node *CreateByTail()

{{

struct Node *head, *p, *q;struct Node *head, *p, *q;

head = new Node;head = new Node; // // 头节点头节点head->next = NULL;head->next = NULL;

p=head;p=head;

Page 12: 七 、结构体与链表(三)

while(true)while(true)

{{

int d;int d;

cin>>d;cin>>d;

if(d == 0) break;if(d == 0) break;

q=new Node;q=new Node; // step 1 // step 1

q->data=d;q->data=d; // 2// 2

q->next=head->next;q->next=head->next; // 3// 3

head->next=q;head->next=q; // 4// 4

}}

return head;return head;

}}int main()int main()

{{

Node *h= CreateByFront();Node *h= CreateByFront();

return 0;return 0;

}}

// // 新结点链到表头新结点链到表头struct Node *CreateByFront() struct Node *CreateByFront()

{{

struct Node *head, *q;struct Node *head, *q;

head = new Node;head = new Node; // // 头节头节点点head->next = NULL;head->next = NULL;

Page 13: 七 、结构体与链表(三)

7.7.3 遍历单链表// 从头开始,顺序输出void Traverse (struct Node *head)

{

struct Node *p = head->next;

while(p != NULL)

{

cout << p->data << endl; // 访问当前节点p = p->next;

}

}

int main()int main(){{

Node *h= CreateByTail();Node *h= CreateByTail();Traverse(h);return 0;return 0;

}}

Page 14: 七 、结构体与链表(三)

7.7.4 查找// 从头顺序查找,若找到,返回指向该节点的指针,否则返回 NULL

Node * Locate(Node *head, int target)

{

struct Node *p=head->next;

while(p!=NULL)

{

if(p->data == target) break; // found

p=p->next; // not found , continue

}

return p;

}

int main()int main(){{

Node *h= CreateByTail();Node *h= CreateByTail();Node *p=Locate(h, 8);return 0;return 0;

}}

Page 15: 七 、结构体与链表(三)

7.7.5 插入操作

e

aiai-1

Page 16: 七 、结构体与链表(三)

{{if(pos<0) return;if(pos<0) return;

struct Node *p=head;struct Node *p=head;

while(p!=NULL&&pos>0)while(p!=NULL&&pos>0){{

p = p->next;p = p->next;pos--;pos--;

}}

if(pos==0)if(pos==0){{

Node *q=new Node *q=new Node;Node;

q->data=e;q->data=e;q->next=p->next;q->next=p->next;p->next=q;p->next=q;

}}}}

voidvoid InsertAfter(Node *head, int InsertAfter(Node *head, int pos, int e)pos, int e)

int main()int main(){{

Node *h= CreateByTail();Node *h= CreateByTail();InsertAfter(hInsertAfter(h, 1, 8);return 0;return 0;

}}

Page 17: 七 、结构体与链表(三)

ai

7.7.6 删除操作

ai-1 ai+1

Page 18: 七 、结构体与链表(三)

void void dele(Node *head, int target )dele(Node *head, int target ){{

Node *q = head;Node *q = head;

while(q->next!=NULL)while(q->next!=NULL){{

if ( q->next->data == target ) break; if ( q->next->data == target ) break; q = q->next;q = q->next;

}}if ( q->next==NULL) return; if ( q->next==NULL) return;

Node *p=q->next;Node *p=q->next; q->next=q->next->next;q->next=q->next->next; delete p;delete p;}}

int main()int main(){{

Node *h= CreateByTail();Node *h= CreateByTail();dele(hdele(h, 8);return 0;return 0;

}}

Page 19: 七 、结构体与链表(三)

1062 最短距离的两点 ( 必做 ) 1116 竞赛排名 ( 必做 ) 1129 成绩排名 ( 必做 ) 1204 足球联赛排名 ( 必做 ) 1420 获奖 ( 必做 ) 1355 Clay Bully ( 必做 ) 1046 EXCEL 排序 ( 选做 ) 1211 确定最终排名 ( 选做 ) 1245 节约有理 ( 选做 ) 1354 Grandpa is Famous( 选做 )

课后练习(要求用结构体完成)