第2章 线性表(三) 1/.

Slides:



Advertisements
Similar presentations
起原 漢朝人將虎視作百獸之王的象徵。相傳一隻虎滿5百歲時,其毛色就會變白,所以白虎成為了一種神物的代表。當帝王具備德政或是天下太平的時候才會出現。因為白色代表西方,所以白虎為守護西方之神祇。 常常與龍相提並論的就是「白虎」;虎,為百獸之長,其威猛和傳說中降服鬼物的能力,使得它變成了屬陽的神獸,常常跟著龍在四象中,一起出動,「雲從龍,風從虎」成為降服鬼物的一對最佳拍檔。
Advertisements

第4章 條件判斷與迴圈 Java 2 程式設計入門與應用.
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
第一章 C语言概述 计算机公共教学部.
数据结构概论 第2章 线性表 董黎刚 浙江工商大学信电学院
第三章 鏈結串列 Linked List.
计算机硕士专业基础—C语言 赵海英
第8章 查找 在英汉字典中查找某个英文单词的中文解释;在新华字典中查找某个汉字的读音、含义;在对数表、平方根表中查找某个数的对数、平方根;邮递员送信件要按收件人的地址确定位置等等。可以说查找是为了得到某个信息而常常进行的工作。 计算机、计算机网络使信息查询更快捷、方便、准确。要从计算机、计算机网络中查找特定的信息,就需要在计算机中存储包含该特定信息的表。如要从计算机中查找英文单词的中文解释,就需要存储类似英汉字典这样的信息表,以及对该表进行的查找操作。本章将讨论的问题即是“信息的存储和查找”。
第二章 线性表 1 线性表的逻辑结构及其基本操作 2 线性表的顺序存储结构 3 线性表的链式存储结构 4 静态链表 5 应用实例.
第二章 线性表.
第2章 线性表 2.1 线性表的概念及运算 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 一元多项式的表示及相加.
C语言基础——指针的高级应用 Week 05.
幼兒美勞試教 我想飛~~~~~ 四幼二A D 莊小萱 D 林昀儒 D 劉思妤
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
Linked List Operations
單向鏈結串列 Singly Linked Lists.
第2章 线性表 线性结构 是一个数据元素的有序集合。.
第7章 结构体、联合体和枚举类型 本章导读 本章主要知识点 《 C语言程序设计》 (Visual C++ 6.0环境)
程式設計 博碩文化出版發行.
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第3章 C 語言的基本知識.
C++语言程序设计 C++语言程序设计 第六章 指针和引用 第十一组 C++语言程序设计.
·线性表的定义及ADT ·线性表的顺序存储结构 ·线性表的链接存储结构 · 单向循环链表 · 双链表、双向循环链表 · 一元多项式的加法
经济生活模块备考知识.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
第2章 线性表 2.1 线性表的基本概念 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 线性表的应用 2.5 有序表 本章小结.
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第五章 指针 5.1 指针的概念和定义 5.2 指针运算 5.3 指针和数组 5.4 字符串指针 5.5 指针数组 5.6 指向指针的指针
第二章 C++对C 在非面向对象方面的改进 更简洁,更安全.
第八章 查找表 8.1静态查找表 8.2动态查找表 8.3哈希表及其查找.
本章重点难点 重点:顺序查找、二分查找、二叉排序树查找以及散列表查找的基本思想和算法实现。
第 3 讲 线性表(一).
C语言 程序设计基础与试验 刘新国、2012年秋.
第二章 线性表.
第一章 绪论.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
内容回顾 线性表的定义和特点 线性表的顺序存储及查找、插入和删除.
第四讲 线性表(三) 1/.
第九章 查找表 9.1静态查找表 9.2动态查找表 9.3哈希表及其查找.
6.3 遍历二叉树和线索二叉树(知识点二) 遍历二叉树 一、问题的提出
第三章 栈和队列.
第三章 链表 单链表 (Singly Linked List) 循环链表 (Circular List) 多项式及其相加
王玲 第 2 章 线性表 王玲 2019/2/25.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
六、函数 教学目标: 函数的概念、定义、调用和返回 带自定义函数的程序设计 递推算法 递归思想及算法实现 函数的参数传递方式 C语言程序设计.
3.1 线性表及逻辑结构 3.2 线性表的顺序存储 3.3 线性表的链式存储 3.4 链式存储结构的应用
第三章 链表 单链表 循环链表 多项式及其相加 双向链表 稀疏矩阵.
第五章 递归与广义表 递归的概念 递归过程与递归工作栈 递归与回溯 广义表.
程式結構&語法.
C语言复习3----指针.
第二章 数组 作为抽象数据类型的数组 顺序表 多项式抽象数据类型 稀疏矩阵 字符串 小结.
第 二 章 数据类型、运算符与表达式.
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
第二章 线性表.
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
問題解決與流程圖 高慧君 台北市立南港高中 2006年12月22日.
#include <iostream.h>
服務教育課程 改制說明會 學生事務處 服務教育組
第七章  数 组.
第4章 鏈結串列(Linked Lists) 4-1 動態記憶體配置-(6) 4-2 鏈結串列的基礎-(7)
第三章 线性表 3.1 线性表的类型定义 3.2 顺序存储的线性表 3.3 链式存储的线性表 3.4 有序表 3.5 顺序表和链表的综合比较.
单片机应用技术 (C语言版) 第4章 C51程序设计入门
Chapter 2 Entity-Relationship Model
由一个佯谬看涡旋电流的存在 PB 田鸿翔 指导老师 万树德.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
本节内容 1.二叉排序树的定义 2.二叉排序树的查找操作 3.二叉排序树的插入操作 4.二叉排序树的删除操作 5.二叉排序树的总结
第六章 复合数据类型 指针的声明与使用 数组的声明与使用 指针与数组的相互引用 字符串及相关库函数 new与delete
Presentation transcript:

第2章 线性表(三) 1/

2.7 线性表的应用 线性表的合并 有序表的合并 1 2

2.7.1 线性表的合并 问题描述: 假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合 A=AB 2.7.1  线性表的合并 问题描述: 假设利用两个线性表La和Lb分别表示两个集合A和B,现要求一个新的集合 A=AB La=(7, 5, 3, 11) Lb=(2, 6, 3) La=(7, 5, 3, 11, 2, 6) .

【算法步骤】 依次取出Lb 中的每个元素,执行以下操作: 在La中查找该元素 如果找不到,则将其插入La的最后 .

【算法描述】 void union(List &La, List Lb){ La_len=ListLength(La); Lb_len=ListLength(Lb); for(i=1;i<=Lb_len;i++){ GetElem(Lb,i,e); if(!LocateElem(La,e)) ListInsert(&La,++La_len,e); }

2.7.2  有序表的合并 问题描述: 已知线性表La 和Lb中的数据元素按值非递减有序排列,现要求将La和Lb归并为一个新的线性表Lc,且Lc中的数据元素仍按值非递减有序排列. La=(1 ,7, 8) Lb=(2, 4, 6, 8, 10, 11) Lc=(1, 2, 4, 6, 7 , 8, 8, 10, 11) .

【算法步骤】-有序的顺序表合并 (1) 创建一个空表Lc (2) 依次从 La 或 Lb 中“摘取”元素值较小的结点插入到 Lc 表的最后,直至其中一个表变空为止 (3) 继续将 La 或 Lb 其中一个表的剩余结点插入在 Lc 表的最后 La=(1 ,7, 8) Lb=(2, 4, 6, 8, 10, 11) Lc=(1, 2, 4, 6, 7 , 8, 8, 10, 11) .

【算法描述】-有序的顺序表合并 else *pc++=*pb++; } T(n)= void MergeList_Sq(SqList LA,SqList LB,SqList &LC){ pa=LA.elem; pb=LB.elem; //指针pa和pb的初值分别指向两个表的第一个元素 LC.length=LA.length+LB.length; //新表长度为待合并两表的长度之和 LC.elem=new ElemType[LC.length]; //为合并后的新表分配一个数组空间 pc=LC.elem; //指针pc指向新表的第一个元素 pa_last=LA.elem+LA.length-1; //指针pa_last指向LA表的最后一个元素 pb_last=LB.elem+LB.length-1; //指针pb_last指向LB表的最后一个元素 while(pa<=pa_last && pb<=pb_last){ //两个表都非空 if(*pa<=*pb) *pc++=*pa++; //依次“摘取”两表中值较小的结点 else *pc++=*pb++; } while(pa<=pa_last) *pc++=*pa++; //LB表已到达表尾 while(pb<=pb_last) *pc++=*pb++; //LA表已到达表尾 }//MergeList_Sq T(n)= S(n)= O(ListLength(LA)+ ListLength(LB))

有序链表合并--重点掌握 将这两个有序链表合并成一个有序的单链表。 要求结果链表仍使用原来两个链表的存储空间, 不另外占用其它的存储空间。 表中允许有重复的数据。

有序链表合并--重点掌握 La 1 7 8 Lb 2 4 6 8 10 11 La 1 2 4 6 7 8 10 11 合并后

【算法步骤】-有序的链表合并 (1)Lc指向La (2) 依次从 La 或 Lb 中“摘取”元素值较小的结点插入到 Lc 表的最后,直至其中一个表变空为止 (3) 继续将 La 或 Lb 其中一个表的剩余结点插入在 Lc 表的最后 (4) 释放 Lb 表的表头结点

有序链表合并(初始化) La 1 7 8 Lc = pc pa Lb 2 4 6 8 10 11 pb

有序链表合并( pa->data < =pb->data ) La(Lc ,pc) 1 7 8 pa Lb 2 4 6 8 10 11 pb pc->next = pa; 16:15

有序链表合并( pa->data < =pb->data ) La(Lc) 1 1 7 8 Pc Pa Lb 2 4 6 8 10 11 pb pc->next = pa; pc= pa; 16:15

有序链表合并( pa->data < =pb->data ) La(Lc) 1 1 7 8 Pc pa = pa->next; Pa Lb 2 4 6 8 10 11 pb pc->next = pa; pc= pa; 16:15

有序链表合并( pa->data >pb->data ) La(Lc) 1 1 7 8 Pc pa Lb 2 4 6 8 10 11 pb pc->next = pb; 16:15

有序链表合并( pa->data >pb->data ) La(Lc) 1 1 7 8 pa Lb 2 2 4 6 8 10 11 Pc pc= pb; pb pc->next = pb; 16:15

有序链表合并( pa->data >pb->data ) La(Lc) 1 1 7 8 pa Lb 2 2 4 6 8 10 11 Pc pc= pb; pb =pb->next; pb pc->next = pb; 16:15

pc-> next=pa?pa:pb; 有序链表合并 La(Lc) 1 7 8 pa(NULL) 2 4 6 8 10 11 pc pb pc-> next=pa?pa:pb; 16:15

有序链表合并 合并后 La(Lc) 1 7 8 delete Lb; 2 4 6 8 10 11 16:15

【算法描述】-有序的链表合并 void MergeList_L(LinkList &La,LinkList &Lb,LinkList &Lc){ pa=La->next; pb=Lb->next; pc=Lc=La; //用La的头结点作为Lc的头结点 while(pa && pb){ if(pa->data<=pb->data){ pc->next=pa;pc=pa;pa=pa->next;} else{pc->next=pb; pc=pb; pb=pb->next;} pc->next=pa?pa:pb; //插入剩余段 free(Lb); //释放Lb的头结点} T(n)= S(n)= O(1) 16:15

思考:要求合并后的表无重复数据,如何实现? La(Lc) 1 7 8 2 4 6 8 10 11 提示:要单独考虑 pa->data = =pb->data

2.8 案例分析与实现 案例2.1 :一元多项式的运算 P(x) = 10 + 5x - 4x2 + 3x3 + 2x4 10 5 -4 数组表示 (每一项的指数i隐含在其系数pi的序号中) P(x) = 10 + 5x - 4x2 + 3x3 + 2x4 指数 (下标i) 1 2 3 4 系数p[i] 10 5 -4 Rn(x) = Pn(x) + Qm(x) 线性表R = (p0 + q0,p1 + q1,p2 + q2,…,pm + qm,pm+1,…,pn)

线性表P =((p1, e1), (p2, e2),…,(pm, em)) 案例2.2 :稀疏多项式的运算 多项式非零项的数组表示 (a)A(x) = 7 + 3x + 9x8 + 5x17 (b)B(x) = 8x + 22x7 − 9x8 下标i 1 2 3 系数a[i] 7 9 5 系数 b[i] 8 22 -9 指数 17 线性表P =((p1, e1), (p2, e2),…,(pm, em)) 创建一个新数组c 分别从头遍历比较a和b的每一项 指数相同,对应系数相加,若其和不为零,则在c中增加一个新项 指数不相同,则将指数较小的项复制到c中 一个多项式已遍历完毕时,将另一个剩余项依次复制到c中即可

链式存储结构 A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 顺序存储结构存在问题 存储空间分配不灵活 运算的空间复杂度高 链式存储结构 typedef struct PNode { float coef;//系数 int expn; //指数 struct PNode *next; //指针域 }PNode,*Polynomial;   A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 -1 7 3 1 9 8 5 17 22 -9 A B

多项式创建---【算法步骤】 ① 创建一个只有头结点的空链表。 ② 根据多项式的项的个数n,循环n次执行以下操作: 生成一个新结点*s; 设置一前驱指针pre,用于指向待找到的第一个大于输入项指数的结点的前驱,pre初值指向头结点; 指针q初始化,指向首元结点; 循链向下逐个比较链表中当前结点与输入项指数,找到第一个大于输入项指数的结点*q; 将输入项结点*s插入到结点*q之前。

多项式创建---【算法描述】 void CreatePolyn(Polynomial &P,int n) {//输入m项的系数和指数,建立表示多项式的有序链表P P=new PNode; P->next=NULL; //先建立一个带头结点的单链表 for(i=1;i<=n;++i) //依次输入n个非零项 { s=new PNode; //生成新结点 cin>>s->coef>>s->expn; //输入系数和指数 pre=P; //pre用于保存q的前驱,初值为头结点 q=P->next; //q初始化,指向首元结点 while(q&&q->expn<s->expn) //找到第一个大于输入项指数的项*q pre=q; q=q->next; } //while s->next=q; //将输入项s插入到q和其前驱结点pre之间 pre->next=s; } //for }

A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 pa pb -1 7 3 1 9 8 5 17 22 -9 A 3 1 9 8 5 17 22 -9 A B pa pb

多项式相加 A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 pa pb A -1 7 3 1 9 8 5 17 3 1 9 8 5 17 B -1 8 1 22 7 -9 8 pb

多项式相加 A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 pa pb A -1 7 11 1 9 8 5 11 1 9 8 5 17 B -1 8 1 22 7 -9 8 pb

多项式相加 A17(x)=7+3x+9x8+5x17 B8(x)=8x+22x7-9x8 pa pb A -1 7 11 1 9 8 5 11 1 9 8 5 17 B -1 8 1 22 7 -9 8 pb

A17(x) = 7 + 3x + 9x8 + 5x17 B8(x) = 8x + 22x7 − 9x8

多项式相加---【算法步骤】 ① 指针p1和p2初始化,分别指向Pa和Pb的首元结点。 ② p3指向和多项式的当前结点,初值为Pa的头结点。 ③ 当指针p1和p2均未到达相应表尾时,则循环比较p1和p2所指结点对应的指数值(p1->expn与p2->expn),有下列3种情况: 当p1->expn等于p2->expn时,则将两个结点中的系数相加,若和不为零,则修改p1所指结点的系数值,同时删除p2所指结点,若和为零,则删除p1和p2所指结点; 当p1->expn小于p2->expn时,则应摘取p1所指结点插入到“和多项式”链表中去; 当p1->expn大于p2->expn时,则应摘取p2所指结点插入到“和多项式”链表中去。 ④ 将非空多项式的剩余段插入到p3所指结点之后。 ⑤ 释放Pb的头结点。

polynomial AddPolyn(polynomial &pa, polynomial &pb) { polynomial qc; /* 用来指向新链表的尾结点的 */ polynomial qa; /* 指向第一个链表的当前结点 */ polynomial qb; /* 指向第二个链表的当前结点*/ polynomial temp; /* 删除结点时做临时变量用 */ ElemType a, b; /* 分别存放两个链表当前结点的数据 */ float sum; /* 存放两个链表中当前结点的系数和 */ qc = pa; qa = pa->next; qb = pb->next; while( qa && qb ) a = qa->data.expn; b = qb->data.expn; switch( cmp(a,b) ) 34/

qa->data.coef=sum; case -1: /* 第一个链表中当前结点的指数值小 */ qc->next=qa; qc=qa; qa=qa->next; break; case 0: /* 指数值相等 */ sum = a.coef + b.coef; if( sum != 0.0) { qa->data.coef=sum; } else temp=qa; free(temp); 35/

case 1: /* 第一个链表中当前结点的指数值大 */ qc->next = qb; qc = qb; temp = qb; qb = qb->next; free(temp); break; case 1: /* 第一个链表中当前结点的指数值大 */ qc->next = qb; qc = qb; } /* End of Switch */ } /* End of while(!qa && !qb) */ qc->next = qa?qa:qb; /* qa?qa:qb三目运算 */ free(pb); return (pa); } 36/

案例2.3 :图书信息管理系统 实验1---基于线性表的图书信息管理系统

图书顺序表 图书链表

typedef struct {//顺序表 Book *elem; int length; } SqList; struct Book { char id[20];//ISBN char name[50];//书名 int price;//定价 }; typedef struct LNode {//链表 Book data; struct LNode *next; }LNode,*LinkList;

小结 1、掌握线性表的逻辑结构特性是数据元素之间存在着线性关系,在计算机中表示这种关系的两类不同的存储结构是顺序存储结构(顺序表)和链式存储结构(链表)。 2、熟练掌握这两类存储结构的描述方法,掌握链表中的头结点、头指针和首元结点的区别及循环链表、双向链表的特点等。 16:15

小结 3、熟练掌握顺序表的查找、插入和删除算法 4、熟练掌握链表的查找、插入和删除算法 5、能够从时间和空间复杂度的角度比较两种存储结构的不同特点及其适用场合 16:15

16:15 顺 序 表 链 表 空间 存储空间 预先分配,会导致空间闲置或溢出现象 动态分配,不会出现闲置或溢出现象 存储密度 顺 序 表 链 表 空间 存储空间 预先分配,会导致空间闲置或溢出现象 动态分配,不会出现闲置或溢出现象 存储密度 不用为表示结点间的逻辑关系而增加额外的存储开销,存储密度等于1 需要借助指针来体现元素间的逻辑关系,存储密度小于1 时间 存取元素 随机存取,时间复杂度为O(1) 顺序存取,时间复杂度为O(n) 插入、删除 平均移动约表中一半元素,时间复杂度为O(n) 不需移动元素,确定插入、删除位置后,时间复杂度为O(1) 适用情况 ① 表长变化不大,且能事先确定变化的范围 ② 很少进行插入或删除操作,经常按元素序号访问数据元素 ① 长度变化较大 ② 频繁进行插入或删除操作 16:15

算法设计题 1. 设计一个算法,通过一趟遍历,将链表中所有结点的链接方向逆转,且仍利用原表的存储空间。 1. 设计一个算法,通过一趟遍历,将链表中所有结点的链接方向逆转,且仍利用原表的存储空间。  【算法步骤】从首元结点开始,逐个地把链表L的当前结点p插入新的链表头部 16:15

p q p q p q p L L  标志后继结点q 修改指针(将p插入在头结点之后) 重置结点p(p重新指向原表中后继) a1 a2 16:15

算法设计题 2.将两个非递减的有序链表合并为一个非递增的有序链表。要求结果链表仍使用原来两个链表的存储空间,不另外占用其他的存储空间。表中允许有重复的数据。 16:15

(2) 依次从 La 或 Lb 中“摘取”元素值较小的结点插入到 Lc 表的表头结点之后,直至其中一个表变空为止 【算法步骤】 (1)Lc指向La (2) 依次从 La 或 Lb 中“摘取”元素值较小的结点插入到 Lc 表的表头结点之后,直至其中一个表变空为止 (3) 继续将 La 或 Lb 其中一个表的剩余结点插入在 Lc 表的表头结点之后 (4) 释放 Lb 表的表头结点 16:15

第2题实现过程动态演示 q q pa pa pa La 12 23 34 45 56 q q pb pb Lb 11 32 43 48 54 ∧ 32 43 48 54 Lc ∧ 16:15

算法设计题 3.设计一个算法,通过一趟遍历在单链表中确定值最大的结点。 【算法步骤】类似于求n个数中的最大数 可假设第一个结点最大,用指针pmax指向。 然后用pmax依次和后面的结点进行比较,发现大者则用pmax指向该结点。 这样将链表从头到尾遍历一遍时,pmax所指向的结点就是最大者。 其中的比较语句形式如下: if(p->data > pmax->data) pmax=p; 16:15

作业 使用C语言实现多项式加法运算。 实验一:线性表的操作及应用 49/