1 / 88

线性表回顾

线性表回顾. 线性表的定义. 线性表是由 n(n≥0) 个数据元素 a 1 , a 2 , … , a n 组成的有限序列。 n 定义为表的长度 (n=0 时称为空表 ) 。 将非空的线性表 (n > 0) 记作: (a 1 , a 2 , … , a n ) 数据元素 a i (1≤i≤n) 只是个抽象符号,其具体含义在不同情况下可以不同。. 线性表的存储结构. 顺序存储 —— 数组类型 连续的一片存储空间 链式存储 —— 指针变量 能将不连续空间连接起来. 线性表的操作运算. 建立线性表 求线性表的长度 查找一个元素 删除一个元素 插入一个元素

Télécharger la présentation

线性表回顾

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 线性表回顾

  2. 线性表的定义 线性表是由n(n≥0)个数据元素a1,a2,…,an组成的有限序列。 n定义为表的长度(n=0时称为空表)。 将非空的线性表(n>0)记作:(a1,a2,…,an) 数据元素ai(1≤i≤n)只是个抽象符号,其具体含义在不同情况下可以不同。

  3. 线性表的存储结构 顺序存储——数组类型 连续的一片存储空间 链式存储——指针变量 能将不连续空间连接起来

  4. 线性表的操作运算 建立线性表 求线性表的长度 查找一个元素 删除一个元素 插入一个元素 线性表中元素排序

  5. 指针变量及线性链表

  6. 指针变量 指针变量的定义方法 type 标识符=^基类型 type point = ^integer; type ch =^char; type point = ^nodenode = record ……end; var p1,p2: point;

  7. 指针变量 指针变量的使用方法 动态申请存储单元 new(指针变量); new(p1); nil 释放动态存储单元 dispose(指针变量); dispose(p1);

  8. 指针类型 type link=^stu; stu = record name: string[10]; number: integer; end; var t1, t2: link; begin new(t1); new(t2); …… dispose(t1); dispose(t2); end;

  9. 指针类型 一个基类型是记录类型的指针类型可以作为其记录类型的一个字段 type classes = ^students;students = record name: string[8]; num: 1..100;link: classes;end;

  10. 指针类型 Pascal规定所有数据类型都必须先定义后使用,但只有在定义指针类型时可以例外。如上面classes的基类型students出现在本身定义之前是允许的。 这里的指针类型是递归定义的。

  11. 指针变量的赋值和操作 赋值操作 由于指针变量存储的是new()操作所得到的内存地址,因此直接访问指针变量只能得到一个地址,而不能得到真正的数据。要得到指针所指向的数据,应使用如下方式(假设指针为p) p^

  12. 赋值操作 new(clas1); new(clas2); clas1^.name := 'liming'; clas1^.number := 90; clas1^.link := clas2; clas2^.name := 'wangping'; clas2^.number := 80; clas2^.link := nil; clas1 liming 90 clas2 wangping 80 nil

  13. 指针变量的操作 相同基类型的指针变量的赋值操作 p1 := p2 给指针变量赋nil值 p1 := nil 指针变量的关系运算 p1 = p2 p1 <> nil

  14. p和p^的区别 p和p^ p1:=p2 p1^:=p2^ P1^ 35 28 p1 P1^ 35 p2 P2^

  15. 线性链表 指针变量通常与记录一起使用,而记录与记录之间往往存在着一种相互连接的顺序。 按一定的顺序,用指针将记录链接在一起而形成的一个链,我们称之为线性链表。 head 1142 1635 1789 2214 1142 Dat1 Dat2 Dat3 Dat4 1635 1789 2214 nil

  16. 线性链表 线性链表中我们称每一个基本的存储空间为“结点”,其形式如下: 链表中的一个元素称为表头,最后一个元素称为表尾。指向表头的指针称为头指针。 数据域 指针域

  17. 建立线性链表 线性链表的类型描述type link = ^node;node = record data: …; next: link;end;var head, p: link; 链表是一种动态存储管理结构,在使用过程中根据需要动态分配空间。

  18. 建立线性链表 建立线性链表的过程,实质是不断生成新结点,并将新结点链接到链表中的过程。 常用的建立方法有:插入表头、插入表尾和按特定要求插入链表中间。

  19. 插入表头建表 算法思路 从空表开始; 读入一个数据,申请一个新结点; 将数据放入新结点的数据域中; 将新结点的指针域指向头指针; 将头指针指向新结点; 重复操作直至结束。

  20. 插入表头建表 read(ch); head := nil; while ch <> '#' do begin new(p); p^.data := ch; p^.next := head; head := p; read(ch); end;

  21. 插入表尾建表 算法思路 从空表开始; 读入一个数据,申请一个新结点; 将数据放入新结点的数据域中; 将新结点的指针域指向nil; 将表尾结点指针域指向新结点; 重复操作直至结束。

  22. 插入表尾建表 read(ch); head := nil; tail := nil; while ch <> '#' do begin new(p); p^.data := ch; p^.next := nil; if head = nil then begin head := p; tail := p; end else begin tail^.next := p; tail := p; end; read(ch); end;

  23. 线性链表的遍历与输出 p := head; while p <> nil do begin 访问或输出p^.data; p := p^.next; end;

  24. 线性链表结点的插入 插入到表头 p^.next := head; head := p; 插入到表中 p^.next := q^.next; q^.next := p; q := q^.next; 插入到表尾 r^.next := p; r := p;

  25. 线性链表结点的删除 删除头结点 p := head; head := head^.next; dispose(p); 删除其他结点 q^.next := p^.next; dispose(p);

  26. 线性链表例题 有两个多项式Y1和Y2,请编写程序将两个多项式合并同类项。 Y1=3X7+5X6-4X5-3X2-8X-2 Y2=9X12-6X8-5X7-5X6+X4-8X3+6X2+7X+3 Y=9X12-6X8-2X7-4X5+X4-8X3+3X2-X+1

  27. 线性链表例题 问题分析 多项式合并同类项的方法是将指数相同的项系数相加,指数不变。 多项式的每一项的表示方法可以有两种: 用记录数组,A[i].cof和A[i].exp 用指针变量表示,指针变量的基类型是一个记录,其结构为:系数域、指数域和指向下一项的地址域。

  28. 线性链表例题 由于事先不知道多项式的指数范围,使用记录数组会比较麻烦,而使用线性链表动态存储会比较适合。 数据结构type link =^node;node = record cof, exp: longint; next: link;end;

  29. 线性链表例题 算法描述 建立两个多项式的线性链表L1和L2(按降幂排列) 对于两个线性链表的头结点,执行以下操作: 如果指数域相同,则将系数域相加后放入L1头结点。如相加后系数不为零,则将L1头结点从L1中取出并插入L尾部,将L2头结点删除;否则将L1和L2头结点都删除。 如果指数域不同,则将指数域大的结点从其链表中取出并插入L尾部。 当任意一个链表为空后,将另一个链表的剩余部分直接插入到L尾部。

  30. 循环链表 循环链表(Circular Linked List)是线性表的另一种形式的链式存储表示。它的特点是表中最后一个结点的指针域指向头结点,整个链表成为一个由链指针相链接的环,并且将头指针设成指向最后一个结点。空的循环链表由只含一个自成循环的头结点表示。

  31. 循环链表 循环链表的操作和单链表基本一致,差别仅在于,判别链表中最后一个结点的条件不再是“后继是否为空”,而是“后继是否为头结点”。

  32. 双向链表 双向链表中有两条方向不同的链,即每个结点中除next域存放后继结点地址外,还增加一个指向其直接前趋的指针域front。

  33. 双向链表 双向链表的类型描述 type link = ^node; node = record data: …; front, next: link; end; 双向链表的操作 双向链表的基本操作与单向链表类似,只要注意处理好front指针就可以了。

  34. 链表例题 Joseph问题:有n个人围坐在一个圆桌周围,把这n个人依次编号为1~n。从编号为1的人开始顺时针报数,数到m1的人出列;然后逆时针方向报数,数到m2的人出列。问:最后谁出列?

  35. 链表例题 问题分析 首先静态数组和链表都可以作为本题的存储结构,但考虑到题目中的“出列”操作,采用链表更加适合; 题中要求能双向报数,因此应采用双项链表; 同时报数过程中,当报到排头或排尾后,还需要从排尾或排头继续报数,因此应采用循环链表; 综上所述,采用双向循环链表,正数时沿next指针遍历,逆数时沿front指针遍历。“出列”的数据直接从链表中删除。

  36. 链表例题 双向循环链表的建立 head := nil; read(n); for i := 1 to n do begin new(p); p^.data := i; p^.next := nil; if head = nil then begin head := p; tail := head end else begin tail^.next := p; p^.front := tail end; tail := p; read(ch) end; tail^.next := head; head^.front := tail;

  37. 链表例题 顺时针报数 for i := 1 to m – 1 do p := p^.next; 出列 q := p^.front; q^.next := p^.next; p^.next^.front := q; dispose(p); 逆时针?

  38. 广义表

  39. 广义表的定义 广义表是线性表的推广。它是指一个表(空表或是由非空元素组成的表),其元素可以是某个确定类型的元素,也可以是子表组成。 (a1, a2, a3, B4, a5 , a6 , B7 …, an) 其中B4、B7分别为一个子表。 B4 = (b1, b2, b3, …, bi) B7 = (d1, d2, …, dj)

  40. 广义表的定义 A = ( ) B = (e) C = (a,(b,c,d)) D = (A,B,C)=((),(e),(a,(b,c,d))) E = ((a,(a,b),((a,b),c)))

  41. 广义表的定义 广义表通常用圆括号括起来,用逗号分隔其中的元素。 为了区分原子和子表,书写时用大写字母表示广义表的子表,用小写字母表示原子。 若广义表 L 非空(n≥1),则a1是L的表头,其余元素组成的表(a2,…,an)称为L的表尾。 广义表是递归定义的。

  42. 广义表的常用表示 E = ( ) E是一个空表,其长度为0。 L = (a, b) L是长度为2的广义表,它的两个元素都是原子,因此它是一个线性表。 A = (x, L) = (x, (a, b)) A是长度为2的广义表,第一个元素是原子x,第二个元素是子表L。

  43. 广义表的常用表示 B = (A, y) = ((x, (a, b)), y) B是长度为2的广义表,第一个元素是子表A,第二个元素是原子y。 C = (A,B) = ((x,(a,b)),((x,(a,b)),y)) C的长度为2,两个元素都是子表。 D = (a,D) = (a,(a,(a,(…)))) D的长度为2,第一个元素是原子,第二个元素是D自身,展开后它是一个无限的广义表。

  44. 广义表的结构 A=() B=(e) C=(a,(b,c,d)) D=(A,B,C) 树形结构

  45. 广义表的基本运算 计算广义表的长度 广义表的输入和输出 建立广义表

  46. 广义表的应用 建立广义表 输入广义表 输出广义表

  47. 广义表的存储结构 由于广义表中元素及子表中的元素多少不固定,所以一般用动态链接结构。 其结点可表示为 Tag(0,1) Data(Link) Next

  48. 广义表的存储结构 A=() B=(e) C=(a,(b,c,d)) nil A 0 e ^ B 0 a 1 ^ C 0 b 0 c 0 d ^

  49. 练习 画出下列广义表的链接存储结构 A = (a,b,c) B = (a,(b,(c))) C = ((a,b),(c,d)) D = (a,(b,(c,d)),(e)) E = ((a,(b,( ) ,c),((d) ,e)))

  50. 广义表类型的定义 广义表类型的定义和链表定义比较接近,但需要使用可变记录类型。 type node= ^stu; stu = record next: node; case tag: 0..1 of 0: da: …; 1: link: node; end; end;

More Related