第11章C语言程序设计链表PPT课件

合集下载

C语言链表课件

C语言链表课件

return counter;
}//Count_LinkList
Void ChangeLinkList(LinkList &L) { LinkList p, q, s, r, t; q=null; r=L; t=null; //r指示原表的表尾,q是临时表 的表头指针,t指示临时表的表尾,p指示当前正在处理的结点 p=L→next; while(p) { if(p→data %2 == 1) { // p结点是奇数结点 s = p; r→next = p→next; //从原表中删除奇 数结点 s→data = s→data + 1; s→next = null; if(!q) { q = s; t = s ; } //在临时表中插入第一 个结点 else { t→next = s; t = s; } }//if else r = r→next; p = p→next; //处理下一个结点 }//while r→next=q; //将临时表链接到原表之后 }//ChangeLinkList
链表
结点(数据元素) = 元素(数据元素的映象) + 指针(指示后继元素存储位置) 结点 元素(data) 指针(next)
用一组地址任意的存储单元存放线性表中的数据元素。
链表:以“结点的序列”表示线性表
使用内存分配函数,动态申请和释放堆中的存储空间。
P124
struct node{//定义节点类型 int data; node * next; };
void main( ) { node * h; h=CreList( ); PrintList(h); }
node *CreList()
{node A_node; node *head; //首地址 node* s; //当前结点 head = NULL; printf("\n Please input the number ( 0 the end):\t"); scanf("%d",&A_node.data);

C语言-链表(课堂PPT)

C语言-链表(课堂PPT)

内存释放函数原形:void free(void *p); 功能:释放p所指向的内存块。
包含文件:malloc.h、stdlib.h中均有其原型声明。
C 程序设计
第十一章 结构体与共用体 NWPU—CC—ZhangYanChun
5
5) 采用链表的意义
与定长数据结构数组相比,链表能更好地利用 内存,按需分配和释放存储空间。
head
1048 p1 2101
1370 p1 2304
1012
2918
89.5
90
85
操作:
1370
1012
NULL
pp22
p2
p1=(struct student *)malloc(len); scanf("%ld,%f", &p1->num, &p1->score);
p2->next=p1; p2=p1; p2->next=NULL;
/*使p2也指向新节点*/ /*末尾节点next赋值0*/
C 程序设计
第十一章 结构体与共用体 NWPU—CC—ZhangYanChun
11
【例】建立并输出有3名学生数据的单链表。
#include <stdio.h> #include <math.h> #define N 3 struct student { long num;
int i, len; sqrt(5.5);
float score; struct student *next; }; void main( ) {┇ }
/*包含NULL的定义*/ /*结构体类型定义*/ /*自引用结构体指针*/
C 程序设计

《C语言链表》课件

《C语言链表》课件
了解如何删除链表中的指定节点
详细描述
删除链表中的节点需要找到要删除的节点,修改其前一个节点的指针,使其指向要删除节点的下一个 节点,然后将要删除节点的指针置为NULL。如果要删除的是头节点或尾节点,还需要对头指针或尾 指针进行相应的修改。
遍历链表
总结词
了解如何遍历链表中的所有节点
VS
详细描述
遍历链表需要从头节点开始,依次访问每 个节点,直到达到链表的尾部。在遍历过 程中,可以使用一个指针变量来指向当前 节点,每次循环将指针向后移动一个节点 ,即修改指针的next指针。
链表和循环链表的主要区别在于它们的最后一个节点指向的方向。在链表中,最后一个节点指向NULL; 而在循环链表中,最后一个节点指向第一个节点。循环链表具有更好的性能,但实现起来相对复杂一些 。
05
总结与展望
总结链表的重要性和应用场景
总结1
链表作为C语言中一种基本的数据结构,在计算机科学中 有着广泛的应用。通过学习链表,可以更好地理解数据 结构的基本概念,提高编程能力和解决实际问题的能力 。
详细描述
合并两个有序链表可以通过比较两个链表的 节点值来实现。从头节点开始比较,将较小 的节点添加到结果链表中,并将指针向后移 动。重复此过程直到其中一个链表为空。如 果还有剩余的节点,将其添加到结果链表的 末尾。这种方法的时间复杂度为O(n),其中
n为两个链表中节点的总数。
04
常见错误与注意事项
内存泄漏问题
内存泄漏定义
在C语言中,内存泄漏是指在使用动 态内存分配函数(如malloc、calloc 、realloc等)分配内存后,未能正确 释放这些内存,导致程序运行过程中 不断占用越来越多的内存,最终可能 导致程序崩溃或性能下降。

C语言课件 链表

C语言课件 链表

3.处理动态链表所需的函数
上例是比较简单的,所有结点都是在程序中定义 的,不是临时开辟的,也不能用完后释放,这种链表 称为“静态链表”。 前面讲过,链表结构是动态生地分配存储的,即 在需要时才开辟一个结点的存储单元 以便插入或追 加节点,删除节点后需要释放节点占用的内存单元。 C 语言提供了相应的函数。
⑴ void *malloc(unsigned int size) :在内存的动态存储区中分 配一个长度为size的连续空间。成功,则返回一个void型的空指针, 否则,返回NULL. 分配内存的字节数。
使用方法: ptr=malloc(size);
返回空类型的指针。 成功:返回内存的地址。 失败:返回NULL。 ⑵void free(ptr) 作用: 释放ptr指向的内存空间。 (3)void *calloc(unsigned n,unsigned size) 在内存的动态区 存储中分配n个长度为size的连续空间。函数返回分配域的起始 地址;如果分配不成功,返回0。
删除结点的函数: struct student *del (struct student *head,int num) {struct student *p1,*p2; if (head==NULL) {printf ("\nlist is null\n");} p1=head; while (p1->num!=num && p1->next!=NULL) {p2=p1;p1=p1->next;} if (p1->num==num) {if (p1==head) head=p1->next; else p2->next=p1->next; printf ("delete:%d\n",num); } else printf ("%ld not been found!",num); return(head); }

C语言_链表ppt课件

C语言_链表ppt课件
} 许多问题中,有时候为了操作方便,需要在第一个节点之前增加一个
特殊的节点,称为头节点,它的data字段不含信息或根据问题的需要 存放特殊信息。
2、链表的遍历(显示链表)
一个非递归算法
以下函数disp()用于显示头节点为*h的链表的所有节点 数据域。
void disp(struct Node *h) { struct Node *p=h; printf("输出链表:"); if(p==NULL) printf("空表\n"); else { while (p->next!=NULL) { printf("%4d",p->data); p=p->next; } printf("%4d\n",p->data); }
在链表结尾出插入一个元素
p
data
首先要用一个循环语句找到q
q
q=h;
h
...
NULL
while(q->next!=NULL)
q=q->next;
p
然后执行插入语句:
data
p->next=NULL;
q
q->next=p;
h
...
NULL
p
data
q
h
...
NULL
在链表中间插入一个元素
p
data
}
单链表的插入
.
3、链表的插入(头指针的情况下)
对于插入有以下几种情况 在一个空链表上插入一个元素。 (即要插入位置前方和后方均无元素) 从链表表头处插入一个元素 (即要插入的位置前方无元素,后方有元素) 从链表结尾处处插入一个元素 (即要插入的位置后方五元素,前方有元素) 从链表的中间插入 (即要插入的位置前方和后方均有元素) 其中第三种情况可以按照第四种情况处理,但有一定特殊性所以将 其分开 注意:产生新的节点必须用malloc或者calloc开辟空间

C语言_链表

C语言_链表

24
§11.5 链表的删除操作
p
Head
101 Zhang 90
103 Wang 80
101 Zhao 70
105 N U Li L 60 L
(a) head指示已有链表
q Head p
101 Zhang 90
103 Wang 80
101 Zhao 70
105 N U Li L 60 L
(b) 删除第3个结点
图11-2 删除第n个结点
25
(8) 返回链表头head。
20
§11.4 链表的插入操作
p Head
101 Zhang 90
103 Wang 80
105 Li 70
NU L
q
L
104 Zhao 70
r Head 101 Zhang 90 103 Wang 80 q
p 105 Li 70
NU
L
L
104 Zhao 60
图11-1 将指针q所指结点插入第2个结点之后
17
§11.4 链表入操作
在第n个结点之后插入一个新结点 ,插入操作步骤:
(1) q指针指向新结点,i为已访问过的结点数;
(2) p=head,r指向p结点的前一个结点;
(3) i++,r=p,p=p->next,p结点往前移动一个结点;
(4) 若i<n且p!=NULL,则重复(3);
3
§11.1 链表的概念
某3位同学的物理成绩分别为96,89,93。分别 用数组和链表存储这些数据的示意图如下:
a
3个元素的数组: float a[3]; 3个节点的链表:
613 93
609 89

C语言链表详解PPT课件

撤消原来的链接关系。 两种情况: 1、要删的结点是头指针所指的结点则直接操作; 2、不是头结点,要依次往下找。 另外要考虑:空表和找不到要删除的结点
26
链表中结点删除
需要由两个临时指针: P1: 判断指向的结点是不是要删除的结点 (用于寻找); P2: 始终指向P1的前面一个结点;
27
图 11.19
4
结点里的指针是存放下一个结点的地址
Head
1249
1249
A 1356
1356
B 1475
1475
C 1021
1021
D Null
1、链表中的元素称为“结点”,每个结点包括两 个域:数据域和指针域;
2、单向链表通常由一个头指针(head),用于指 向链表头;
3、单向链表有一个尾结点,该结点的指针部分指
7
(4)删除操作是指,删除结点ki,使线性表的长度 减1,且ki-1、ki和ki+1之间的逻辑关系发生如下变 化:
删除前,ki是ki+1的前驱、ki-1的后继;删除后,ki-1 成为ki+1的前驱,ki+1成为ki-1的后继.
(5)打印输出
8
一个指针类型的成员既可指向其它类型的结构体数 据,也可以指向自己所在的结构体类型的数据
(x7,y7)
为了表示这种既有数据又有指针的情况, 引入结构这种数据类型。
3
11.7 用指针处理链表
链表是程序设计中一种重要的动态数据结构, 它是动态地进行存储分配的一种结构。
动态性体现为: 链表中的元素个数可以根据需要增加和减少,不 像数组,在声明之后就固定不变;
元素的位置可以变化,即可以从某个位置删除, 然后再插入到一个新的地方;
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
printf("%ld %5.1f\n", p->num, p->score); p = p->next; }while(p != NULL); }
19
四、删除一个结点 删除一个结点的算法:
20
应考虑以下情况: 1、找到需要删除的结点,用p1指向它。 并用p2指向p1的前一个结点。 2、要删除的结点是头结点。
指向空 */ p1 = (struct student *)malloc(LEN); /* 创
建一个新结点p1 */ p2 = p1; /* 表尾p2也指向p1 */ scanf("%ld,%f", &p1->num, &p1->score);
/* 读入第一个结点的学生数据 */
17
while(p1->num != 0) /* 假设num=0表示输入结束 */
6
7
8
9
10
11
12
13
通过以上分析,可以得到创建链表的算 法,其中,n=1表示创建的是第一个结点。
14
15
程序:
#include "stdio.h" #include "alloc.h" #include "stdlib.h"
struct student {
long num; float score; struct student *next; };
21
22
3、要删除的结点不是头结点
23
根据以上情况分析,得到删除一个结点 的算法:
24
程序:
在链表head中删除学号为num的结点。以表头 指针head和需要删除的结点的num(学号)为 参数,返回删除操作后的链表表头。
struct student * del(struct student *head, long num) {
组中插入、删除数据项时,需要移动其它数据项)

链表有单向链表、双向链表、环形链表等形式。以
单向链表为例、
1
整体 概述
一 请在这里输入您的主要叙述内容

请在这里输入您的主要 叙述内容
三 请在这里输入您的主要叙述内容
2
3
链表有一个“头指针”head,它指向链表的第一 个元素。
链表的一个元素称为一个“结点”(node)。 结点中包含两部分内容,第一部分是结点数据 本身,如图中的A、B、C、D所示。结点的 第二部分是一个指针,它指向下一个结点。
18
二、输出链表 只要已知表头结点,通过p->next可以找到下一 个结点,从而可以输出链表的全部结点数据。 void print(struct student *head) {
struct student *p; printf("\nNow, These %d records are:\n", n); p = head; if (p == NULL) return; do {
25
while(num != p1->num && p1->next != NULL) /* 查找要删除的结 点 */
{
p2 = p1;
p1 = p1->next;
} if (num == p1->num) /* 找到了 */
{ if (p1 == head) /* 要删除的是头结点 */
struct student *p1; /* 指向要删除的结点 */ struct student *p2; /* 指向p1的前一个结点 */
if (head == NULL) /* 空表 */ {
printf("\n List is NULL\n"); return (hea(struct student)
/* 注意,"#define NULL 0"不需要,因为, NULL已在stdio.h中定义 */
int n;
struct student * creat() /* 创建链表,并返回 16
{ struct student *head; /* 表头 */ struct student *p1; /* 新建结点 */ struct student *p2; /* 表尾结点 */ n = 0; /* 结点数为0 */ head = NULL; /* 还没有任何结点,表头为
{
n = n + 1; if (n == 1) head = p1;
/* 第一个新建结点是表头
*/ else
是新建结点 */
p2->next = p1; /* 原表尾的下一个结点
p2 = p1; /* 新建结点成为表尾 */
p1 = (struct student *)malloc(LEN); /* 新建一个结 点 */
§11.7 用结构体指针处理链表
一、链表概述
链表是一种最常见的数据结构,它动态地进行存储
分配。
数组:必须事先定义固定的长度(元素个数),不
能适应数据动态地增减的情况。当数据增加时,可
能超出原先定义的元素个数;当数据减少时,造成
内存浪费。
链表动态地进行存储分配,可以适应数据动态地增
减的情况,且可以方便地插入、删除数据项。(数
scanf("%ld,%f", &p1->num, &p1->score); /* 读入 新建结点的学生数据 */
}
free(p1); /* 对于num=0的结点,未加入链表,应删 除其空间 */
p2->next = NULL; /* 输入结束,表尾结点的下一个结 点为空 */
return (head); /* 返回表头指针 */ }
并返回指向该空间起始地址的指针。若分配失 败(系统不能提供所需内存),则返回NULL。
2、void * calloc(size_t n, size_t size) 在动态存储区分配n个长度为size的连续
空间,并返回指向该空间起始地址的指针。若 分配失败(系统不能提供所需内存),则返回
NULL。
3、void free(void * ptr)
最后一个结点称为“表尾”,表尾结点的指针为 空(NULL)。
在链表中插入一个结点,比如,在结点A后插入 结点P,只需使P指向B,使A指向P。
在链表中删除一个结点,比如删除结点C,只需 4
5
链表需要动态地进行存储分配,在C语言中, 使用以下函数进行动态存储分配和释放。
1、void * malloc(size_t size) 在动态存储区分配长度为size的连续空间,
相关文档
最新文档