当前位置:首页 >> 工学 >>

第 3 章 栈和队列


第三章 栈和队列

开始学习本章前要掌握:
? 从数据结构角度看,栈和队列仍属于线性 结构,具有线性结构的共同特征; ? 学习本章时,要注意到栈和队列所具有的 线性结构的共性,更要掌握其个性; ? 栈和队列是操作受限的线性结构; ? 本章具体内容见本章目录。

本章目录
? 3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和实现

? 3.2 栈的应用举例
3.2.1 数制转换 3.2.2 括号匹配的检验 3.2.3 行编辑程序 3.2.4 表达式求值 * 3.3 栈与递归的实现

? 3.4 队列
3.4.1 队列的抽象数据类型定义 3.4.2 链队列-队列的链式表示和实现 3.4.3 循环队列-队列的顺序存储结构

*3.5 离散事件模拟

主要内容
? 知识点
? ? ?

栈与队列的特征 栈与递归 循环队列

? 重点难点
? ? ? ?

栈的操作 递归 循环队列 栈与队列的综合应用

本章目录
? 3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和实现

? 3.2 栈的应用举例
3.2.1 数制转换 3.2.2 括号匹配的检验 3.2.3 行编辑程序 3.2.4 表达式求值 * 3.3 栈与递归的实现

? 3.4 队列
3.4.1 队列的抽象数据类型定义 3.4.2 链队列-队列的链式表示和实现 3.4.3 循环队列-队列的顺序存储结构

*3.5 离散事件模拟

栈(Statck)的定义

? 栈 是操作受限制的线性表 ? 定义:仅在表尾进行插入或删除操作的线性表; ? 概念: ? 栈顶:在栈顶操作,是表尾,通常用top表示 ; ? 栈底:bottom,是表头; ? 空栈: 空表; ? 通常栈底固定,栈顶移动。

栈示意图
栈顶top an … a3 a2 a1 表尾

栈底 bottom

表头

操作原则:后进先出(Last In First Out), LIFO 举例:餐馆的盘子

3.1.1 栈的抽象数据类型定义
ADT Stack{ 数据对象:D={ai|ai?ElemSet,i=1,2,...,n,n>=0} 数据关系:R={<ai-1,ai>|ai-1,ai?D,i=2,...,n} 基本操作: 栈初始化:InitStack ( &S ) 判栈空:StackEmpty(S) 入栈:Push( &S,e ) 出栈:Pop( &S,&e) 取栈顶元素:GetTop( S ,&e) 清空栈: ClearStack (&S) 求栈长:StackLength(S) }ADT Stack

3.1.2 栈的表示和实现

顺序存储结构:顺序栈; ? 链式存储结构:链栈;
?

顺序栈
? 利用一组地址连续的存储单元依次自 栈底到栈顶存放栈的数据元素. ? 在数组上实现时,栈底位置可以设置 在数组的任一个端点,而栈顶是随着 插入和删除而变化的,可以用一个整 形变量top存放栈顶的指针,数据入 栈或出栈时使整形变量 top分别加1或 减1。

顺序栈的类型定义
#define STACK_INIT_SIZE 100 #define STACKINCREMENT 10 typedef struct { SElemType *base; //栈底指针 SElemType *top; //栈顶指针 int stacksize; //存储空间大小 }SqStack;

用顺序栈实现栈的运算(1)
初始化
Status InitStack (SqStack &S) {//构造一个空栈S S.base=(ElemType *)malloc ( STACK_INIT_SIZE*sizeof(ElemType) ); if(!S.base) exit(OVERFLOW); S.top=S.base; S.stacksize=STACK_INIT_SIZE; return OK; }

用顺序栈实现栈的运算(2)
取栈顶元素 Status GetTop(SqStack S,ElemType &e)
{ //若栈不空,则用e返回S的栈顶元素,并返回OK; //否则返回ERROR

if(S.base==S.top) return ERROR; //请思考该语句的作用 e=*(S.top-1); return OK;
}

用顺序栈实现栈的运算(3)
入栈
Status Push(SqStack &S, ElemType e) {// 插入元素e为新的栈顶元素 if(S.top-S.base>=S.stacksize) //栈满,追加空间 { S.base =(ElemType *)realloc(S.base, (S.stacksize+STACKINCREMENT) *sizeof(ElemType)); if(!S.base ) exit(OVERFLOW); S.top=S.base+S.stacksize; S.stacksize+=STACKINCREMENT; } *S.top++=e; return OK; }

用顺序栈实现栈的运算(4)
出栈 Status Pop(SqStack &S,ElemType &e) if(S.base==S.top) return ERROR; e=*--S.top; return OK; }

{//若栈不空,则删除S的栈顶元素,用e返回其值,并返回OK; //否则返回ERROR

用顺序栈实现栈的运算(5)
判栈空(补充算法)

int StackEmpty(SqStack S) {//判断栈S是否为空 if (S.top==S.base) return TRUE; else return FALSE; }

知识扩展 链栈

链栈
? 用链式存储结构实现的栈称为链栈。 ? 通常链栈可用单链表表示,因此其结点结构与 单链表的结构相同。 链栈结点的类型描述 :
typedef struct StackNode { ElemType data; struct StackNode *next; }StackNode,*LinkStack;

由于栈只在栈顶操作,因此,通常不设头结点。

链栈图示
top

栈顶



栈底

用链栈实现栈的运算(1)
链栈的初始化 LinkStack LinkedStackInit() {//构造一个空栈,栈顶指针为top LinkStack top; top=NULL; return top; }

用链栈实现栈的运算(2)
判栈空
int LinkStackEmpty(LinkStack top) {//判定栈S是否是空栈 if(top==NULL) return TRUE; else return FALSE; }

用链栈实现栈的运算(3)
入栈
LinkStack Push(LinkStack top,ElemType x) //插入元素x为新的栈顶元素,链栈用栈顶指针top表示 {s=(LinkStack) malloc(sizeof(StackNode)); //创建一个新结点 s->data=x; //设置新结点的数据域 s->next=top; //设置新结点的指针域 top=s; //设置新栈顶指针 return top; }

用链栈实现栈的运算(4)
退栈
ElemType Pop (LinkStack top) {//若栈S不空,则删除S的栈顶元素,并返回其值 if(top!=NULL) {x = top->data; p = top; top = top->next; free (p); return x; } else {printf(“栈空\n”);exit(0);} }

本章目录
? 3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和实现

? 3.2 栈的应用举例
3.2.1 数制转换 3.2.2 括号匹配的检验 3.2.3 行编辑程序 3.2.4 表达式求值 * 3.3 栈与递归的实现

? 3.4 队列
3.4.1 队列的抽象数据类型定义 3.4.2 链队列-队列的链式表示和实现 3.4.3 循环队列-队列的顺序存储结构

*3.5 离散事件模拟

3.2 栈的应用举例
? 数制转换 ? 表达式求值

算法3.1

栈的应用:数制转换

? 把十进制数转换为八进制数。 ? N = ( N / d ) * d + N mod d; ? 例如: (1348)10 = (2504)8
? ? ? ?

1348 / 8 = 168, 168 / 8 = 21, 21 / 8 = 2, 2 / 8 = 0,

1348 % 8 = 4 168 % 8 = 0 21 % 8 = 5 2%8=2

最低位

最高位

数制转换的非递归算法
void conversion( ) {// 把十进制转换为八进制 InitStack( S ); scanf( “%d”, &N ); while( N ) { Push( S, N%8 ); N = N/8; } while( !StackEmpty( S ) ) { Pop( S, e ); printf( “%d”, e ); } }

算法3.4 表达式求值
算术表达式中运算符(+,-,*,/等)的优先规则 设置两个工作栈: 运算符栈S1和操作数栈S2。 S2存放表达式的运算结果。 算法思想: 1 首先置操作数栈S2为空栈,置运算符栈的栈底为表 达式的起始符#(优先级最低)。 2 依次读入表达式的每个字符ch,直至表达式结束:
若ch是操作数,则进S2栈; 若ch是运算符,若其优先级不高于栈顶运算符的优先级时, 则取出栈S2的栈顶和次栈顶的两个元素以及栈S1的栈顶运 算符,进行相应的运算,并将结果放入栈S2中;如此下去, 直至ch的优先级高于栈顶运算符的优先级,将ch入S1栈。

举例: 3*(5-2)
步骤 optr栈S1 opnd栈 S2 输入字符 主要操作

-------------------------- 1 # 3*(5-2)# push(s2,’3’) 2 # 3 *(5-2)# push(s1,’*’) 3 #* 3 (5-2)# push(s1,’(’) 4 #*( 3 5-2)# push(s2,’5’) 5 #*( 35 -2)# push(s1,’-’) 6 #*(35 2)# push(s2,’2’) 7 #*(352 )# operate(‘5’,’-’,’2’ ) 8 #*( 33 )# pop(s1){消除一对括号} 9 #* 33 # operate(‘3’,’*’,’3’ ) 10 # 9 # return(gettop(s2))

算法3.4 表达式求值
? PperandType EvaluateExpression() ? { ? InitStack(OPTR); Push(OPTR, ‘#’); //optr是运算符栈 ? InitStack (OPND); c=getchar(); //opnd是运算数栈 ? while( c!=‘#’ || GetTop(optr)!=‘#’ ) ? if( !In(c,OP)) { Push(opnd,c); c=getchar();} //不是运算符就进栈 ? else switch( Precede(GetTop(OPTR), c) ) ? {case ‘<’: //栈顶元素优先级低 ? Push(OPTR,ch); ch=getchar(); break; ? case ‘=’: //脱括号并接收下一字符 ? pop(OPTR,x); ch=getchar(); break; ? case ‘>’: //退栈并将运算结果入栈 ? pop(OPTR, theta); ? pop(OPND, b); pop(OPND, a); ? push(OPND, operate(a,theta, b)); break; ? }//switch ? return GetTop(OPND) ? }

本章目录
? 3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和实现

? 3.2 栈的应用举例
3.2.1 数制转换 3.2.2 括号匹配的检验 3.2.3 行编辑程序 3.2.4 表达式求值 * 3.3 栈与递归的实现

? 3.4 队列
3.4.1 队列的抽象数据类型定义 3.4.2 链队列-队列的链式表示和实现 3.4.3 循环队列-队列的顺序存储结构

*3.5 离散事件模拟

3.3 栈与递归的实现
过程的嵌套调用图示:

栈与递归过程
? 递归:若在一个函数、过程或者数据结构定 义的内部,直接(或间接)出现定义本身的 应用,则称它们是递归的,或者是递归定义 的。 ? 递归过程的应用:
? ? ?

问题的定义是递归的:f(n)=n*f(n-1) 数据结构是递归的:链表 问题的解法是递归的:Hanoi 塔问题

? “递归工作栈”——栈顶为“工作记录”, 包括参数、局部变量以及上一层的返回地址

递归过程的应用(1)
(1)问题的定义是递归的:求n的阶乘n! long Fact(int n) {if(n==1) return(1); else return(n*Fact(n-1)); }

求阶乘(n!)过程的模拟
n=3 n=2 F=3*fac(2) n=1 n=0

fac(3)

F=2*fac(1)

F=1*fac(0)

fac(0)

return fac(3)=3*2*1 return fac(2)=2*1 return fac(1)=1*1

return fac(0)=1

递归过程的应用(2)
(2)数据结构是递归的: 逆序打印无头结点单链表中各结点的值。 void print(LinkedList head) {if (head!=null) {print(head->next); printf(“%d”,head->data);//设元素为整型 } }

递归过程的应用(3)
(3)问题的解法是递归的:Hanoi 塔问题

递归过程的应用(3)

? n阶Hanoi塔问题:假设有三个分别命名为X,Y,Z的塔座, 在X塔座上插有n个直径大小各不相同,依小到大编号 为1,2,…,n的圆盘,要求:把X上的n个圆盘移到Z上, 排列顺序相同,移动规则为: ? 每次只能移动一个园盘; ? 园盘可以在任一塔上做多次移动; ? 在任何时刻,大盘不能压在小盘的上面。
X

Y

Z

用递归实现Hanoi的算法思想
? 使用数学归纳法: ? n = 1, OK; ? 设n = k 时,
? 若可以以Y为辅助塔,把k个盘从X移动到Z;
?

当n = k + 1时,方法:
? 把X中k个盘,以Z为辅助塔,移动到Y; ? 把X中第k+1个盘,移动到Z; ? 把Y中k个盘,以X为辅助塔,移动到Z;

用递归实现Hanoi的算法
void Hanoi( int n, char x, char y, char z ) { if( n == 1 ) move( x, 1, z ); // 把1号盘,从x移到z else {Hanoi( n – 1, x, z, y );// 把n-1个盘从x移到y,z为辅助塔 move( x, n, z ); // 把n号盘,从x移到z Hanoi( n – 1, y, x, z );//把n-1个盘从y移到z,x为辅助塔 } }

Hanoi塔算法的模拟
n=1 n=3 n=2 a?c H(2,a,c,b) H(1,a,b,c)

a?b c?b H(3,a,b,c) a?c H(1,c,a,b)

H(1,b,c,a) H(2,b,a,c)

b?a

b?c

H(1,a,b,c)

a?c

递归算法的优缺点
优点:递归过程结构清晰 程序易读 正确性容易证明 缺点:时间效率低 空间开销大 算法不容易优化 对于频繁使用的算法,或不具备递归功能 的程序设计语言,需要把递归算法转换为 非递归算法。

递归算法转换为非递归算法
有如下方法: ? 采用迭代算法 ? 尾递归的消除 ? 利用栈消除任何递归

将递归转换为非递归
采用迭代算法
long Fact2(int n) {∥用迭代算法求n! x=1; for(i=1;i<=n;i++) x*=i; return x; }∥Fact2
n!

递 归 从 顶 到 底

(n-1)! (n-2)! . . . 2! 1! 0!

迭 代 从 底 到 顶

将递归转换成迭代

使用尾递归的算法
递归算法 void Output1(LinkList L) {∥顺序输出单链表结点数据的递归算法 if(L) {printf(L->data); ∥输出结点的值 Output1(L->next); ∥尾递归调用 } }∥Output1

尾递归的消除(1)
非递归算法

void Output2(LinkedList L) {∥顺序输出单链表结点数据的非递归算法一 p=L; ∥设局部变量p=L Lbl: ∥在第一个可执行语句前设标号 if(p){printf(p->data);∥输出结点的值 p=p->next; ∥修改变量值 goto Lb1; ∥转到第一个可执行语句 } }∥ Output2

尾递归的消除(2)
非递归算法
? void Output3(LinkedList L) ? {∥顺序输出单链表结点数据的非递归算法二 ? p=L; ∥设局部变量p=L ? while(p) ? {printf(p->data); ∥输出结点的值 ? p=p->next; ∥向里一层修改变量值 ? } ? }∥ Output3

利用栈消除任何递归(1)
? 利用栈可以将任何递归函数转换成非递归的 形式,其步骤大致如下: ? 入栈处理
?

?

? ? ?

设一个工作栈代替递归函数中的栈,栈中每个记 录包括函数的所有参数:函数名、局部变量和返 回地址。 所有递归调用语句处,改写成把形参、局部变量 和返回地址入栈的语句。 修改确定本次递归调用时的实在参数之新值。 转到函数的第一个语句。 (转下页)

利用栈消除任何递归(2)
? (接上页) ? 退栈处理
? ?

?

若栈空,算法结束,执行正常返回。 若栈不空,从栈中退出参变量赋给原来入栈时相 对应的参变量,并退出返回地址。 转到执行返回地址处的语句,继续执行。

算法扩展 判断回文
回文指正读和反读都相同的字符序列,写一算法判断含给定的字符串是 否是回文。

int sympthy(char str[],char s[]) { int i=0,j,n; while (str[]!=‘\0’) i++; // 查字符个数 n=i; for(i=0; i<n/2; i++) s[i]=str[i]; //前一半字符入栈 j=i-1; if(n%2==1) i++; //n为奇数时中间字符不用比较 while (i<n && str[i]== s[j]) //比较字符串是否是回文 {i++; j--;} if (i==n) printf(“字符串是回文\n”); else printf(“字符串不是回文\n”); } 如何用栈来实现该算法? }

本章目录
? 3.1 栈
3.1.1 栈的抽象数据类型定义 3.1.2 栈的表示和实现

? 3.2 栈的应用举例
3.2.1 数制转换 3.2.2 括号匹配的检验 3.2.3 行编辑程序 3.2.4 表达式求值 * 3.3 栈与递归的实现

? 3.4 队列
3.4.1 队列的抽象数据类型定义 3.4.2 链队列-队列的链式表示和实现 3.4.3 循环队列-队列的顺序存储结构

*3.5 离散事件模拟

3.4.1 抽象数据类型队列的定义

队列(Queue)定义和概念
? 队列:队列是一种只允许在表的一端插入, 在另一端删除的存取受限的线性表。 ? 概念: ? 队尾rear: 插入端,线性表的表尾。 ? 队头front:删除端,线性表的表头。

队列(Queue)图示
? FIFO(First In First Out)(先进先出表)
出队列
a1 a2 a3 …… an-1

入队列

队 头

队 尾

队列的抽象数据类型
ADT Queue{ 数据对象:D={ai | ai ? ElemSet , i=1,2,... ,n,n>=0} 数据关系:R={<ai-1,ai>|ai-1,ai?D,i=2,...,n} 基本操作: 队列初始化: InitQueue (&Q ) 入队: EnQueue (&Q , e) 出队: DeQueue (&Q, &e ) 读队头元素: GetHead(Q , &e ) 判队空: QueueEmpty (Q) 求队列长: QueueLength(Q) }ADT Queue

队列的表示和实现
链式存储结构:链队列; ? 顺序存储结构:循环队列;
?

3.4.2 链队列
?用链表表示的队列简称为链队列。 ?为便于操作,一个链队列需要分别指示队 头和队尾的两个指针。
front a1 a2 … an ∧ rear

链队列示意图
Q.front a1 a2 … an ∧

Q.rear
Q.front

(a)非空队 Q.front



a1



Q.rear (b) 空队

Q.rear (c) 链队中只有一个元素结点

链队列的类型描述
typedef struct QNode { QElemType data; struct QNode *next; }QNode,*QueuePtr;//链队结点的类型及指针 typedef struct { struct QueuePtr front; //队头指针 struct QueuePtr rear; //队尾指针 }LinkQueue;

链队列的初始化
创建一个带头结点的空队 Status InitQueue(LinkQueue &Q) { Q.front=Q.rear= (QueuePtr)malloc(sizeof(Queue)); //申请头结点 if(!Q.front) exit(OVERFLOW);//内存分配失败 Q.front->next=NULL; return OK; }

链队列的入队
Status EnQueue(LinkQueue &Q , QElemType e) { p=(QueuePtr)malloc(sizeof(QNode)); if( !p ) exit(OVERFLOW); p->data=e; p->next=NULL; //创建新结点p Q.rear->next=p; //将结点p插入队尾 Q.rear=p; //队尾指针指向p结点 }

链队列的出队
出队
Status DeQueue(LinkQueue &Q, QElemType &e) { if(Q.front==Q.rear) return ERROR; //队空 p=Q.front->next; //p指向队头结点 e=p->data; //用e返回被删的队头元素 Q.front->next=p->next; if (Q.rear==p) Q.rear=Q.front;
//只有一个元素时,出队后队空,此时还要修改队尾指针

free(p); return OK;

}

补充算法 链队列的判空
Status QueueEmpty(LinkQueue Q) { if (Q.front==Q.rear) return true; else return false; }

3.4.3 循环队列——队列的顺序表示和实现
? 约定队头指针指向队头元素, ? 队尾指针指向队尾元素的下一个位置
rear
5 4 3 2 1 rear 0

rear rear J1 front front J4 J3 J2 J1

rear J4 J3 J2 J1

front

front

J6 J5 J4 J3 front J2 J1

问题:如何解决“假上溢”现象?

队列的顺序表示和实现
循环队列:

3.4.3 循环队列——队列的顺序表示和实现
循环队列 入队
Q.front J4 4 0 3 1 J3 2
J5 5 Q.rear J5 5 2

Q.front

J4
J3

4 3

0 J6 Q.rear 1

Q.front

J4 J3

4 3

J5 5

Q.rear

0 J6 1 J7 2 J8

Q.front

J4 J3

4 3

J5 5

0 J6 1 J7 2 Q.rear

3.4.3 循环队列——队列的顺序表示和实现
循环队列 出队
Q.front J4 4 0 3 1 J3 2
J5 5 Q.rear Q.front J5 5 2

J4

Q.rear 0 1

4 3

Q.front 4 3 5 2

Q.front

0 1

Q.rear

4 3

J5 5 2

Q.rear
0 1

循环队列
? 空队列条件:
?

Q.rear = = Q.front; Q.rear = = Q.front;

? 满队列条件:
?

问题:如何区别队空和队满 1.牺牲一个存储空间 有三种方法 2.引入一个标志变量区别空和不空 3.使用计数器

3.4.3 循环队列——队列的顺序表示和实现
入队 少用一个空间 队满的条件是??
J5 5 Q.rear Q.front J4

Q.front J4 4 0 3 1 J3 2 J5 5

J3

4 3

J5 5
2

0 J6 Q.rear 1

Q.front

J4 J3

4 3

0 J6 1 J7 2 Q.rear

循环队列类型定义
#define MAXQSIZE 100 typedef struct { QElemType *base; // 数据的存储区 int front; //队头指针 int rear; //队尾指针 }SqQueue; //循环队

循环队列的初始化
5 4 3 2 1 rear 0
front

Q.base

循环队列的初始化
Status InitQueue (SqQueue &Q) { Q.base=(QElemType *) malloc (MAXQSIZE*sizeof(QElemType)); if(!Q.base) exit(OVERFLOW); Q.front=Q.rear=0; return OK; }

求队中元素个数

Q.front 4 3 5 0 J6 1 J7 2 Q.rear

Q.front J4 4 0 3 1 J3 2

J5 5

Q.rear

求队中元素个数
? int QueueLength(SqQueue Q) ? {∥返回队列Q的元素个数
?

return (Q.rear-Q.front+MAXQSIZE)%MAXQSIZE;

? }

循环队列的入队
Status EnQueue(SqQueue &Q,QElemType e) { if((Q.rear+1) % MAXQSIZE==Q.front) return ERROR; //队列满,退出运行 Q.base[Q.rear]=e; Q.rear=(Q.rear+1) % MAXQSIZE; // 指 针 后


return OK;

}

循环队列的出队
Status DeQueue(SqQueue &Q,QElemType &e) { if (Q.front==Q.rear) return ERROR; //队已空,退出运行 e=Q.base[Q.front]; //读出队头元素 Q.front=( Q.front+1) % MAXQSIZE; return OK; //出队完成

//指针后

}

算法补充 循环队列的判空
Status QueueEmpty (SqQueue Q) {if (Q.front==Q.rear) return true; else return false; }

自测题
? 1. 为解决计算机主机与打印机之间速度不匹配问 题,通常设置一个打印数据缓冲区,主机将要输 出的数据依次写入该缓冲区,而打印机则依次从 该缓冲区中取出数据。该缓冲区的逻辑结构应该 是 ? A. 栈 ? B. 队列 ? C. 树 ? D. 图 ? 【2009年全国硕士研究生入学计算机学科专业基础综合试题】

自测题
? 2. 设栈S和队列Q的初始状态均为空,元素 a,b,c,d,e,f,g依次进入栈S。若每个元素出栈后立 即进入队列Q,且7个元素出队的顺序是 b,d,c,f,e,a,g,则栈S的容量至少是 ? A. 1 ? B. 2 ? C. 3 ? D. 4 ? 【2009年全国硕士研究生入学计算机学科专业基础综合试题】

总结
? 第二章和第三章是重点 ? 线性结构 顺序存储 链式存储
线性表 栈 队列 顺序表 顺序栈 循环队列 单链表 链队列

总结
0 1 i-1 i n-1 LIST_INIT_SIZE-1

data

a1

a2



ai-1

ai

ai+1 …

an



top an … a3 a2 a1

rear J4 J3 J2 J1

front

bottom

总结
L 67

23

10

45

36 ∧

Q.front
a1 a2 … an ∧

Q.rear


相关文章:
数据结构第三章栈和队列习题及答案.doc
数据结构第三章栈和队列习题及答案 - 习题 栈和队列 一 单项选择题 1. 在
数据结构第三章 栈和队列_图文.ppt
数据结构第三章 栈和队列 - 中国石油大学,宋会英主讲,严蔚敏、吴伟民,数据结构(c语言版)清华大学出版社,1997.4(一版), 2001.1(2版), 严蔚敏,吴伟民,...
第三章 栈和队列习题答案.doc
第三章 栈和队列习题答案 - 栈和队列习题答案 第三章 栈和队列习题答案 一、基础知识题 3.1 设将整数 1,2,3,4 依次进栈,但只要出栈时栈非空,则可将出...
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 第3章 栈和队列 栈和队列是两种应用非常广泛的数据结构,它
数据结构第3章栈和队列自测题答案.doc
数据结构第3章栈和队列自测题答案 - 一、填空题 二、1. 向量、栈和队列都是
第三章栈和队列.doc
第三章栈和队列 - 第三章 栈和队列 一.选择题 1.栈与一般线性表的区别在于_
DS第三章 栈和队列_图文.ppt
DS第三章 栈和队列 - 第3章 栈和队列 ? ? 3.1 考纲要求和分析 考纲要求 (1)栈和队列的基本概念。 (2)栈和队列的顺序存储结构。 (3)栈和队列的链式存储...
第三章 栈和队列_图文.ppt
第三章 栈和队列 - 第3章 栈和队列 [内容提要] 1. 栈的概念 2. 栈的表示和实现 3. 栈的应用举例 4. 队列的概念 5. 队列的表示和实现 栈的定义 栈(...
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 第三章栈和队列 ? ? 栈 队列 ? 递归 栈 ( Sta
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 2018/5/9 栈和队列是两种特殊的线性表,其操作是线性
第3章 栈和队列(新)_图文.ppt
第3章 栈和队列(新) - 第3章 栈和队列 教学内容 3.1 栈和队列的定义和特点 3.2 案例引入 3.3 栈的表示和操作的实现 3.4 栈与递归 3.5 队列的的表示...
第3章栈和队列_图文.ppt
第3章栈和队列 - 3.1 栈 3.1.1 抽象数据类型栈的定义 ⑴ 栈的定义
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 第三章 栈和队列 3.1.1 栈的定义 栈:限定仅在表的一
第3章 栈和队列_图文.ppt
数据结构第3章 栈和队列 西安航空学院 计算机工程系 第3章 栈和队列内 容 栈和队列的逻辑结构 栈和队列的顺序存储及运算实现栈和队列的链式存储及运算...
第3章___栈及队列.doc
第3章___栈及队列 - 第3章 栈和队列 一 选择题 1. 对于栈操作数据的原
第三章 栈和队列_图文.pdf
第三章 栈和队列 - 第三章 栈和队列主要内容: ?栈的定义与存储结构 ?栈的应用 ?队列的定义与存储结构 ?队列的应用 ? 栈和队列是两种特殊的线性表; ...
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 第3章 栈和队列 3.1 栈 3.2 队列 本小结 3.1 栈 3.1.1 栈的定义 3.1.2 栈的顺序存储结构及 其基本运算实现 3.1.3 栈的链式存储...
第三章栈和队列(作业).doc
第三章栈和队列(作业) - 第三章 栈和队列(作业) 一、判断题 1. 两个栈共
数据结构第三版李春葆第3章 栈和队列_图文.ppt
第3章 栈和队列 3.1 栈 3.2 队列 本小结 3.1 栈 3.1.1 栈的定义 3.1.2 栈的顺序存储结构及其基本运算实现 3.1.3 栈的链式存储结构及其基本运算的实现 ...
第3章 栈和队列_图文.ppt
第3章 栈和队列 - 第3章 栈和队列 栈和队列是两种应用非常广泛的数据结构,它
更多相关标签: