第三章 栈和队列 Stack and Queue 2007.9.

Slides:



Advertisements
Similar presentations
数据结构的引入. 通讯录管理 社团机构管理 校园导航管理 通讯录管理 社团机构管理 校园导航管理.
Advertisements

阻塞操作. 在 linux 里,一个等待队列由一个 wait_queue_head_t 类型的结构来描述 等待队列的初始化: static wait_queue_head_t testqueue; init_waitqueue_head(&testqueue);
第三章 鏈結串列 Linked List.
第二章 线性表 £2.4 线性表的应用 £2.1 线性表的类型定义 £2.2 线性表的顺序存储结构 £2.3 线性表的链式存储结构
第二章 线性表 2.1 线性表的逻辑结构 一. 线性表定义如下:
第二章 线性表 ⒈教学内容:2.1 线性表逻辑结构; 2.2 线性表的顺序存储及运算实现; 2.3 线性表的链式存储和实现。
第二章 线性表 1 线性表的逻辑结构及其基本操作 2 线性表的顺序存储结构 3 线性表的链式存储结构 4 静态链表 5 应用实例.
第二章 线性表.
單向鏈結串列 Singly Linked Lists.
第2章 线性表 线性结构 是一个数据元素的有序集合。.
其他类型的链表主要内容 静态链表 循环链表 双向链表.
第3章 栈和队列.
第6章 佇列(Queues) 6-1 佇列的基礎 6-2 佇列的表示法 6-3 環狀佇列 6-4 雙佇列.
主要内容: 1.第一部分 概述 2.第二部分 线性表、栈、队列
计算机软件技术基础 数据结构与算法(2).
第二章 线性表 线性表 顺序表 链表 顺序表与链表的比较.
数 据 结 构 Ch.2 线性表 计 算 机 学 院 肖明军
补充内容 结构体 概述 定义结构体类型和定义结构体变量 结构体变量的引用 结构体变量的初始化 指针与结构体 用typedef定义类型的别名.
第三章 线性表 3.1 线性表的类型定义 3.2 顺序存储的线性表 3.3 链式存储的线性表 3.4 有序表 3.5 顺序表和链表的综合比较.
数据结构 第二章 线性表.
制作:崔广才
数据结构 Data Structure 中南大学 主讲人:王国军,郑瑾 中南大学信息院计科系
教 师:曾晓东 电 话: E_mail: 计算机软件技术基础 教 师:曾晓东 电 话: E_mail:
第2章 线性表 2.1 线性表的基本概念 2.2 线性表的顺序存储 2.3 线性表的链式存储 2.4 线性表的应用 2.5 有序表 本章小结.
本 章 说 明 2.1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式存储结构 2.4 循环链表和双向链
西安交通大学计教中心 ctec.xjtu.edu.cn
第2章 线性表 线性表抽象数据类型 顺序表 主要知识点 单链表 循环单链表 循环双向链表 静态链表 设计举例.
第 1 章 数据结构 1.1 基本数据结构与算法 1.2 线性表 1.3 栈和队列 1.4 树和二叉树 1.5 查找 1.6 内部排序 65
第十章 C高级程序应用—链表* 10.1链表的基本概念 10.2单向链表 10.3双向链表 10.4应用举例.
第2章 线性表 2.1 线性表 2.2 顺序表 2.3 单链表 2.4 循环单链表 2.5 双向链表 2.6 仿真链表
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
Zhao4zhong1 (赵中) C语言指针与汇编语言地址.
第2章 线性表 丽水学院工学院.
第2章 线性表 2.1 线性表的类型定义 2.2 线性表的顺序表示和实现 2.3 线性表的链式表示和实现 2.4 一元多项式的表示.
线性表是一种最简单的线性结构 线性结构的基本特征为: 线性结构 是 一个数据元素的有序(次序)集 1.集合中必存在唯一的一个“第一元素”;
第 3 讲 线性表(一).
第二章 线性表.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
(知识点三) 2.3 线性表的链式表示和实现 本节将介绍线性表的另一存储结构—— 链式存储及其对应的操作。
线性表练习.
陈海明 副教授 信息学院 计算机系 电子信息类非计算机专业选修课 程序设计实践 陈海明 副教授 信息学院 计算机系
cn/~dongeliu/dsa.html 刘 东 信息学院6系 中国科学技术大学
資料結構 第4章 堆疊.
顺序表的插入.
王玲 第 2 章 线性表 王玲 2019/2/25.
计算机软件技术基础 数据结构与算法(3).
第2章 线性表 本章主要介绍下列内容 线性表的定义和基本操作 线性表的顺序存储结构 线性表的链式存储结构 线性表的应用举例.
3.1 线性表及逻辑结构 3.2 线性表的顺序存储 3.3 线性表的链式存储 3.4 链式存储结构的应用
第三章 栈和队列 第二部分 队列(Queue) 2019/4/8.
严蔚敏、吴伟民编著 清华大学出版社 学习网站:中国网页设计
C++语言程序设计 C++语言程序设计 第七章 类与对象 第十一组 C++语言程序设计.
顺序表的删除.
单链表的基本概念.
顺序查找.
线性结构 线性结构的特点: 线性结构的种类 在数据元素的非空有限集中, (1)存在唯一的一个被称做“第一个”的数据元素;
第 四 讲 线性表(二).
本教學投影片係屬教科書著作之延伸,亦受著作權法之保護。
成绩是怎么算出来的? 16级第一学期半期考试成绩 班级 姓名 语文 数学 英语 政治 历史 地理 物理 化学 生物 总分 1 张三1 115
第二章 线性表.
第三章 数据组织与处理.
本章的基本内容是: ⑴栈和队列的定义及操作特性; 第3章 特殊线性表—栈、队列和串 ⑵栈和队列的两种存储方法和基本运算的实现;
多层循环 Private Sub Command1_Click() Dim i As Integer, j As Integer
实验目的:掌握数据的顺序存储结构及它们在计算机中的操作。 实验内容:
第七讲 栈和队列(二) 1/.
第三章 线性表 3.1 线性表的类型定义 3.2 顺序存储的线性表 3.3 链式存储的线性表 3.4 有序表 3.5 顺序表和链表的综合比较.
插入排序的正确性证明 以及各种改进方法.
第二章 线性表 线性表是一种最简单的线性结构 线性结构是一个数据元素的有序(次序)集.
第二部分 数据结构—— 用面向对象方法与C++描述.
第二章 线性表 东南大学计算机学院 方效林 本课件借鉴了清华大学殷人昆老师 和哈尔滨工业大学张岩老师的课件.
Presentation transcript:

第三章 栈和队列 Stack and Queue 2007.9

生活中的栈与队列 计算机中的栈与队列 栈与队列的特征 栈:表达式的求值、函数的递归调用 队列:打印机任务处理、CPU的进程处理 LIFO(Last In First Out) FIFO(First In First Out)/FIFS(First In First Service)

栈的定义 栈的特征 栈的基本运算 顺序栈的实现 链式栈的实现 第1节 栈 栈的定义 栈的特征 栈的基本运算 顺序栈的实现 链式栈的实现

1.栈(Stack)的定义 栈(Stack)是限制在表的一端进行插入和删除运算的线性表。 栈顶(Top)为可进行插入、删除的一端,另一端为栈底 (Bottom)。 空栈:表中没有元素。 假设栈S=(a1,a2,a3,…an),则a1称为栈底元素,an为栈顶 元素。 栈中元素按a1,a2,a3,…an的次序进栈,退栈的第一个元素 应为栈顶元素。换句话说,栈的修改是按后进先出的原则 进行的。因此,栈称为后进先出表(LIFO)。

3.线性表的基本运算 InitList(L) :初始化,置表L为空 ClearList(L):将表L清空 ListLength(L): 求表L的长度 Insert(L,i,Item) : 插入,在给定的线性表L中,将数据Item插 入到第i个结点的位置。表L长度加1。 Delete(L,i) :删除,在给定的线性表L中,删除第i个元素。 表L的长度减1。 Get(L,i) :获取表L中第i个结点的值。 Locate(L,x) :查找定位。若线性表L中存在一个值为x的结 点,则返回该结点的位置,否则返回空。 GetNext(L,Item,p):取Item的后继结点 GetPrior( L,Item,p ):取Item的前驱结点  

顺序表的存储结构 顺序表存储结构的C语言描述 基于顺序表的运算的实现 第2节 线性表的顺序存储—顺序表 顺序表的存储结构 顺序表存储结构的C语言描述 基于顺序表的运算的实现

1.顺序表的存储结构 顺序表:把线性表的结点 按逻辑顺序依次存放在一 组地址连续的存储单元里。 用这种方法存储的线性表 简称顺序表。 a1 a2 an 内存 顺序表:把线性表的结点 按逻辑顺序依次存放在一 组地址连续的存储单元里。 用这种方法存储的线性表 简称顺序表。 由于C语言中的一维数组也 是采用顺序存储表示,故 可以用数组类型来描述顺 序表。 有效结点 备用空间 ListSize -1

2.顺序表存储结构的C语言描述 a1 a2 an 1 n-1 length 内存 数组下标 # define ListSize 100 typedef int DataType; typedef struc{ DataType data[ListSize]; int length; } SequenList; /*声明变量*/ SequenList *sqlist; 备用空间 ListSize -1

一个具体的例子 # define ClassSize 100 typedef struct stu { char* num; char* name; int english; int c_languge; int data_stru; }StuType; typedef struc{ StuType data[ClassSize]; int class_len; } class_list; class_list *soft_1; 学生成绩表 学号 姓名 大学英语 C语言 数据结构 … A07001 王萍 90 85 95 A07002 马玲 80 A07003 张兰 91 99 A07004 李建 70 84 86 A07005 黄勇 82 76 78 : :

顺序表的地址关系 假设线性表的每个元素需占用m个存储单元,并 以所占的第一个单元的存储地址作为数据元素的 存储位置。则线性表中第i+1个数据元素的存储位 置LOC( a i+1)和第i个数据元素的存储位置LOC(a I ) 之间满足下列关系: LOC(a i+1)=LOC(a i)+m 线性表的第i个数据元素ai的存储位置为: LOC(ai)=LOC(a1)+(i-1)*m

3.基于顺序表的运算的实现 InitList(L) :初始化,置表L为空 ClearList(L):将表L清空 ListLength(L): 求表L的长度 Insert(L,i,Item) : 插入,在给定的线性表L中,将 数据Item插入到第i个结点的位置。表L长度加1。 Delete(L,i) :删除,在给定的线性表L中,删除 第i个元素。表L的长度减1。

Get(L,i) :获取表L中第i个结点的值。 Locate(L,x) :查找定位。若线性表L中存在一 个值为x的结点,则返回该结点的位置,否则返 回空。 GetNext(L,Item,p):取Item的后继结点 GetPrior( L,Item,p ):取Item的前驱结点  

4.顺序表插入算法的时间复杂度分析 Void InsertList(Sequenlist *sqlist,int i, DataType Item) { int j; if (i<1 || i>sqlist.length+1){ printf(“Position error”); return 0 ; } if( sqlist.length >= ListSize ) { printf(“overflow”); return 0; for( j=sqlist.length-1; j>=i-1; j-- )sqlist.data[ j+1]=sqlist.data[ j ]; sqlist.data[ i-1]=x; sqlist.length++;

顺序表插入算法的时间复杂度分析 时间主要耗费在: for( j=sqlist.length-1; j>=i-1; j-- ) sqlist.data[ j+1]=sqlist.data[ j ]; 所需移动结点的次数不仅依赖于表的长度,而且还 与插入位置有关。 最好:当i=n时,结点不需要后移,其时间复杂度O (1); 最坏:当i=0时,结点后移语句将循环执行n次,需 移动表中所有结点,其时间复杂度O(n)

平均复杂度:由于插入可能在表中任何位置上进行,因 此需分析算法的平均复杂度 在长度为n的线性表中第i个位置上插入一个结点, 令Eis(n)表示移动结点的期望值(即移动的平均次数), 则在第i个位置上插入一个结点的移动次数为n-I+1。故 不失一般性,假设在表中任何位置(1≦i≦n+1)上插入结点 的机会是均等的,则在等概率插入的情况下,

也就是说,在顺序表上做插入运算,平均要移动表 上一半结点。当表长 n较大时,算法的效率相当低。 虽然Eis(n)中n的的系数较小,但就数量级而言,它 仍然是线性阶的。因此算法的平均时间复杂度为 O(n)。 问题:请你分析一下删除算法的时间复杂度。

5.顺序表存储结构特点 基本特点:逻辑上相邻的元素,物理上也是相邻 的。 优点 可以直接实现元素的定位,或者说可以随机存取其中的 任意元素 因为数据在存储结构中是连续存储的,任意元素的存储地址可 由公式直接算出。 高级程序设计语言提供的数组类型可以直接定义顺序存 储结构的线性表,使程序实现十分方便。

顺序存储结构的不方便之处: 数据元素最大个数需预先确定,使得高级语言编译系统需 预先分配相应的存储空间。 插入与删除运算的效率很低。 为了保持线性表中的数据元素的顺序,在插入操作和删除操作时需 移动大量数据。 顺序存储结构的线性表的存储空间不便于扩充。 当一个线性表分配顺序存储空间后,如果线性表的存储空间已满, 但还需要插入新的元素,则会发生“上溢”错误,会导致运算的失 败或中断。

2.2 单链表 Link List

复习:关于指针的概念 即 指针 地址 指针 与 指针所指的变量 指针相关的函数 malloc free

1.单链表的存储结构 线性表的逻辑结构 单链表的结点结构 数据域 指针域 单链表的逻辑结构 单链表的存储结构 head 110 135 ……… …… Data_2 200 ……. Data_1 110 …. Data_n Null 135 数据域 指针域 110 135 单链表的逻辑结构 head Data_1 Data_2 … Data_n ^ 165 单链表的存储结构 200

一个具体的例子 head NULL 学号 姓名 大学英语 C语言 数据结构 … A07001 王萍 90 85 95 A07002 马玲 80 A07003 张兰 91 99 A07004 李建 70 84 86 A07005 黄勇 82 76 78 : : head A07001 王萍 90 85 95 A07002 马玲 80 85 90 A07003 张兰 95 91 99 A07004 李建 70 84 86 A07005 黄勇 82 76 78 NULL

一个具体的例子 头指针 head : 165 110 135 165 200 ……… …… A07002 马玲… 200 ……. 学号 姓名 大学英语 C语言 数据结构 … A07001 王萍 90 85 95 A07002 马玲 80 A07003 张兰 91 99 A07004 李建 70 84 86 A07005 黄勇 82 76 78 : : 头指针 head : 165 ……… …… A07002 马玲… 200 ……. A07001 王萍… 110 …. A070046 … Null 135 110 135 165 200

2.单链表存储结构的C语言描述 head 顺序表的描述 # define ListSize 100 typedef int DataType; typedef struc{ DataType data[ListSize]; int length; } SequenList; /*声明变量*/ SequenList *sqlist; typedef int DataType; typedef struc node{ DataType data; struc node *next; } LinkList; /*声明变量*/ LinkList *head; head Data_1 Data_2 … Data_n ^

一个具体的例子 # define ClassSize 100 typedef struct stu typedef struct stu { char* num; char* name; int english; int c_languge; int data_stru; }StuType; typedef struc node{ StuType data; struc node *next ; } class_list; class_list *soft_1_head; # define ClassSize 100 typedef struct stu { char* num; char* name; int english; int c_languge; int data_stru; }StuType; typedef struc{ StuType data[ClassSize]; int class_len; } class_list; class_list *soft_1; 学生成绩表 学号 姓名 大学英语 C语言 数据结构 … A07001 王萍 90 85 95 A07002 马玲 80 A07003 张兰 91 99 A07004 李建 70 84 86 A07005 黄勇 82 76 78 : :

基于单链表的运算的实现 InitList(L) :初始化,置表L为空 ClearList(L):将表L清空 ListLength(L): 求表L的长度 Insert(L,i,Item) : 插入,在给定的线性表L中,将 数据Item插入到第i个结点的位置。表L长度加1。 Delete(L,i) :删除,在给定的线性表L中,删除 第i个元素。表L的长度减1。

Get(L,i) :获取表L中第i个结点的值。 Locate(L,x) :查找定位。若线性表L中存在一 个值为x的结点,则返回该结点的位置,否则返 回空。 GetNext(L,Item,p):取Item的后继结点 GetPrior( L,Item,p ):取Item的前驱结点  

单链表算法的时间复杂度 O(1) O(n) InitList(L) ClearList(L) Insert(L,i,Item) ListLength(L) Delete(L,i) Get(L,i) GetNext(L,Item,p) Locate(L,x) GetPrior( L,Item,p) O(1) O(n)

void build( int n ) { linklist void build( int n ) { linklist *q; char ch; int i; printf("\n input %2d data: \t",n); head=(struct link *)malloc(sizeof(struct link)); q=head; scanf("%d",&q->data); for(i=2;i<=n;i++){ q->next=(struct link *)malloc(sizeof(struct link)); q=q->next; } q->next=NULL; 单链表的建立

单链表存储结构特点 不能随机存取,查找速度慢 基本特点:逻辑上相邻的元素,物理上不一定相 邻的。 优缺点 是一种动态结构,整个存储空间为多个链 表共用 不需预先分配空间 指针占用额外存储空间 不能随机存取,查找速度慢

2.3 其他形式的链表

2.3.1 循环链表 循环链表的逻辑结构 单链表的逻辑结构 循环链表的空表 循环链表是表中最后一个结点的指针指向头结点, 使链表构成环状。 特点:从表中任一结点出发均可找到表中其他结点, 提高查找效率。 单链表的逻辑结构 循环链表的逻辑结构 Data_1 Data_2 Data_n ^ … Data_1 Data_2 Data_n … head 循环链表的空表

循环链表的操作 循环链表的操作与单链表基本一致,循环条件不同 单链表: p->next==NULL 循环链表: p->next==head

void build( int n ) { linklist void build( int n ) { linklist *q; char ch; int i; printf("\n input %2d data: \t",n); head=(struct link *)malloc(sizeof(struct link)); q=head; scanf("%d",&q->data); for(i=2;i<=n;i++){ q->next=(struct link *)malloc(sizeof(struct link)); q=q->next; } q->next=head; 循环链表的建立

讨论:如何将两个链表合并? 利用单链表如何实现?P47 EX4 Data_1 Data_2 Data_n ^ … Data_1 Data_2 ha Data_1 Data_2 Data_m ^ … hb

利用循环链表如何实现? 表头指针与表尾指针的使用 … Data_1 Data_n Data_2 … Data_1 Data_m Data_2 ha ra Data_1 Data_2 Data_m … hb rb

2.3.2 双向循环链表 双向链表的结点结构 prior data next 双向循环链表的逻辑结构 双向循环链表的空表 head 双向循环链表的空表 head 特点:方便查找任一结点的后继和前驱。

双向循环链表的C语言描述 prior data next typedef int DataType; typedef struc Dnode{ DataType data; struc Dnode *prior, next; } DoubleLinkList; /*声明变量*/ DoubleLinkList *head; prior data next

双向循环链表中的插入与删除 void dinsertbefor(dlistnode *p, datatype x) { dlistnode *q=malloc(sizeof(dlistnode)); q—>data=x; q—>prior=p—>prior; q—>next=p; p—>prior—>next=q; p—>prior=q; } void ddeletenode(dlistnode *p) { p–>prior–>next=p–>next; p–>next–>prior=p–>prior; free(p); } 与单链表的插入和删除操作不同的是,在双链表中插入和删除必须同时修改两个方向上的指针。上述两个算是法的时间复杂度均为O(1)。