第 3 章 栈和队列

59
1 第3第 第第第第 第第 第第第第第第第第第 第第第第第第第第第 第第第第第第第第 第第第第第第第第 ,,、、 第第第第第第第 第第第第第第第第 ;() 第第第第第第 第第第第第第第第第 第 第第第第第第 第第第第第 第第第第第第第 ,;(、、) 第第第第第第第 第第 第第第第 ;() 第第第第第第第第第第 第第第第第第第第第第第 第第第第第第第第第 第第第 ,,、 第第第第 第第第第第第第第 第第第 第第第第第 、;:。 第第第第第第第第第第 ()

description

第 3 章 栈和队列. 要求: 了解栈的定义及特点,掌握栈表示和实现,重点是栈初始化、判断栈空和栈满、出栈和入栈操作;(注意栈顶的约定) 栈的应用举例,重点是表达式求值;(了解波兰式、逆波兰式、中缀式等概念) 栈与递归的实现;(系统工作栈) 了解队列的定义及特点,掌握队列的表示和实现,重点是队列初始化、判断队空和队满、出队和入队操作;难点:循环队列。 (离散事件模拟不要求). 进栈. 出栈. 栈顶. a n. ……. 栈 s=(a1,a2,……,an). a 2. 栈底. a 1. 第 3 章 栈和队列. - PowerPoint PPT Presentation

Transcript of 第 3 章 栈和队列

Page 1: 第 3 章  栈和队列

1

第 3 章 栈和队列要求: 了解栈的定义及特点,掌握栈表示和实现,重点

是栈初始化、判断栈空和栈满、出栈和入栈操作;(注意栈顶的约定)

栈的应用举例,重点是表达式求值;(了解波兰式、逆波兰式、中缀式等概念)

栈与递归的实现;(系统工作栈) 了解队列的定义及特点,掌握队列的表示和实现,

重点是队列初始化、判断队空和队满、出队和入队操作;难点:循环队列。

(离散事件模拟不要求)

Page 2: 第 3 章  栈和队列

2

第 3 章 栈和队列栈和队列是两种特殊的线性表,是操作受限的线性

表,称限定性 DS 3.1 栈( stack )

栈的定义和特点•定义:限定仅在表尾进行插入或删除操作的线性表,

表尾—栈顶 top ,表头—栈底 bottom ,不含元素的空表称空栈

•特点:先进后出( FILO )或后进先出( LIFO )

an

a1

a2

……

...

栈底

栈顶

... 出栈进栈

栈 s=(a1,a2,……,an)

进栈-插入元素

出栈-删除元素

抽象数据类型定义

Page 3: 第 3 章  栈和队列

3

栈的表示和实现•顺序栈 一维数组 s[M] 或先分配一个基本容量,逐段

扩大,动态数组

top=0

1

2

3

4

5

0栈空

栈顶指针 top, 指向实际栈顶后的空位置,初值为 0base 保持不变

top 1

2

3

4

5

0进栈

A

top

出栈

栈满

B

C

D

E

F

设数组维数为 Mtop=0, 栈空,此时出栈,则下溢( underflow)top=M, 栈满,此时入栈,则上溢( overflow)

top

top

toptoptop

1

2

3

4

5

0A

B

C

D

E

Ftop

top

top

top

top

top

栈空

Page 4: 第 3 章  栈和队列

4

typedef struct {

SElemType *base; // 保持不变, NULL 不存在栈

SElemType *top; // 栈顶,指向不用 ( 空 ) 元素,与定义不同

int stacksize;

}SqStack; //( 进 ) 入栈 top++ ,出 ( 退 ) 栈 top--

算法描述InitStack, DestroyStack, ClearStack,StackEmpty, StackLength, GetTop,Push, Pop,StackTraverse

Page 5: 第 3 章  栈和队列

5

•构造一个空栈 SStatus InitStack(SqStack &S){ S.base = (SElemType *)malloc(STACK_INIT_SIZE * sizeof(SElemType)); if (!S.base) exit(OVERFLOW); // 存储分配失败 S.top = S.base; S.stacksize = STACK_INIT_SIZE; return OK;}

•取栈顶元素Status GetTop(SqStack S, SElemType &e) { if (S.top == S.base) return ERROR; e = *(S.top-1); return OK;}

Page 6: 第 3 章  栈和队列

6

• 入栈算法Stutas Push(SqStack &S, SElemType e) { if (S.top – S.base >= S.stacksize { S.base = (SElemType *)realloc(S.base, (S.stacksize+STACKI

NCREMENT)*sizeof(SElemType)); if (!S.base) exit(OVERFLOW); S.top = S.base + S.stacksize;

S.stacksize += STACKINCREMENT;}

*S.top++ = e; // 先赋值,再加指针 return OK;}

Page 7: 第 3 章  栈和队列

7

• 出栈算法Status Pop (SqStack &S, SElemType &e) { if (S.top == S.base) return ERROR;

e = *--S.top; // 先减指针,再取值 return OK;}

0 M-1

栈 1 底 栈 1 顶 栈 2 底栈 2 顶

• 在一个程序中同时使用两个栈

Page 8: 第 3 章  栈和队列

8

• 链栈

栈顶栈顶 ^…...…...top data link

栈底

• 结点定义

• 入栈算法

• 出栈算法

typedef struct node{ int data; struct node *link;}JD;

^…...栈底

toptop

xp

top

^…...栈底

top

q

Page 9: 第 3 章  栈和队列

9

3.2 栈的应用举例

数制转换 N = ( N div d ) x d + N mod d

算法 3.1 P48计算过程 - 入栈打印过程 - 出栈

例 把十进制数 159 转换成八进制数

(159)10=(237)8

1598

198

280 2 3 7

余 7

余 3

余 2top

top

7

top

73

top

732

Page 10: 第 3 章  栈和队列

10

void conversion (int Num) { // 算法 3.1 // 对于输入的任意一个非负十进制整数,打印输出

与其等值的八进制数 InitStack(S); // 构造空栈 while (Num) { Push(S, Num % 8); Num = Num/8; } while (!StackEmpty(S)) { Pop(S,e); printf ("%d", e); } printf("\n");} // conversion

Page 11: 第 3 章  栈和队列

11

括号匹配的检验 园、方、花括号 嵌套匹配

回文游戏:顺读与逆读字符串一样(不含空格)

dad

top 1.读入字符串2.去掉空格(原串)3.压入栈4.原串字符与出栈字符依次比较 若不等,非回文 若直到栈空都相等,回文

字符串:“ madam im adam”

Page 12: 第 3 章  栈和队列

12

void LineEdit( ){

InitStack(S);

ch=gether( );

while(ch!=EOF){

while(ch!=EOF && ch!=‘\n’){

switch(ch){

case ‘#’ : Pop(S,c);

case ‘@’ : ClearStack(S);

default : Push(S,ch);

}

ch=getchar( );

}

transfer; ClearStack(S);

if(ch!=EOF) ch=gethar( );

}

DestroyStack(S);

}

简单行编辑程序 逐行存入,退格 #, 清行 @算法 3.2 P50

迷宫求解,地图四染色

Page 13: 第 3 章  栈和队列

14

表达式求值 运算规则 中缀表达式 后缀表达式( RPN) a*b+c ab*c+ a+b*c abc*+ a+(b*c+d)/e abc*d+e/+

中缀表达式:操作数栈和运算符栈 P53 表 3.1优先关系

例 计算 2+4-3*6

操作数 运算符24

+操作数 运算符

6 -操作数 运算符

6 -36

*

操作数 运算符6 -18

操作数 运算符-12

Page 14: 第 3 章  栈和队列

15

算法基本思想 P53

1) 操作符栈 OPTR 的栈底元素为表达式起始符 ‘ #’,操作数栈 OPND 为空

2)依次读入字符:是操作数则入 OPND 栈,是操作符则要判断

算法 3.4

注意 未考虑匹配,表达式必须正确表达式的前缀、中缀、后缀表示,其中表达式的前缀表示称为波兰式,表达式的后缀表示称为逆波兰式 RPN ( Reverse Polish Notation )。由于逆波兰式用的较多,习惯上称为波兰式 。

中缀表达式 - 算符优先法,括号,双堆栈

前、后缀表达式 - 单堆栈,算符无优先级,无括号

中缀 - > 后缀

Page 15: 第 3 章  栈和队列

16

OperandType EvaluateExpression( ) { // 算法 3.4 算术表达式求值的算符优先算法。 // 设 OPTR 和 OPND 分别为运算符栈和运算数栈, OP 为运算符集合。 InitStack (OPTR); Push (OPTR, '#'); InitStack (OPND); c = getchar(); while (c!= '#' || GetTop(OPTR)!= '#') { if (!In(c, OP)) {Push(OPND, c); c=getchar();} // 不是运算符则进栈 else switch (precede(GetTop(OPTR), c)) { case '<': // 栈顶元素优先权低 Push(OPTR, c); c=getchar(); break; case '=': // 脱括号并接收下一字符 Pop(OPTR, x); c=getchar(); break; case '>': // 退栈并将运算结果入栈 Pop(OPTR, theta); Pop(OPND, b); Pop(OPND, a); Push(OPND, Operate(a, theta, b)); break; } // switch } // while return GetTop(OPND);} // EvaluateExpression

Page 16: 第 3 章  栈和队列

17

后缀表达式求值步骤:1 、读入表达式一个字符2 、若是操作数,压入栈,转 43 、若是运算符,从栈中弹出 2 个数,将运算结果再压入栈4 、若表达式输入完毕,栈顶即表达式值; 若表达式未输入完,转 1

top

4

top

43

top

735

top

例 计算 4+3*5 后缀表达式: 435*+

top

415

top

19

Page 17: 第 3 章  栈和队列

18

过程的嵌套调用

r

主程

srr

r

s

子过程1 r

s

t

子过程2

rst

子过程3

3.3 栈与递归的实现

Page 18: 第 3 章  栈和队列

19

例 递归的执行情况分析

•递归过程及其实现• 递归:函数直接或间接的调用自身叫 ~• 实现:建立递归工作栈

void print(int w){ int i; if ( w!=0) { print(w-1); for(i=1;i<=w;++i) printf(“%3d,”,w); printf(“/n”); }}

运行结果:1 ,2 , 2 ,3 , 3 , 3 ,

Page 19: 第 3 章  栈和队列

20

递归调用执行情况如下:

主程序

(1)

print(w) w=3;

3

print(2);

( 1 ) w=3

top

(2) 输出: 3, 3, 3

w

2

print(1);

( 2 ) w=2 ( 1 ) w=3

top

(3) 输出: 2, 2

w1

print(0);

( 3 ) w=1 ( 2 ) w=2 ( 1 ) w=3

top

(4) 输出:1

w0

( 4 ) w=0 ( 3 ) w=1 ( 2 ) w=2 ( 1 ) w=3

top

w

(3) 输出: 2, 2

(2) 2(1) 3

top

(4) 输出:1

(3) 1(2) 2(1) 3

top

(2) 输出: 3, 3, 3

(1 ) 3

top

返回

(3) 1(2) 2(1) 3

top(4) 0

结束

(1)

Page 20: 第 3 章  栈和队列

•Tower of Hanoi问题• 问题描述:有 A,B,C三个塔座, A 上套有 n 个直径不同的圆盘,按直径从小到大叠放,形如宝塔 ,编号 1,2,3……n 。要求将 n个圆盘从 A移到 C ,叠放顺序不变,移动过程中遵循下列原则:• 每次只能移一个圆盘• 圆盘可在三个塔座上任意移动• 任何时刻,每个塔座上不能将大盘压到小盘上

• 解决方法:• n=1 时,直接把圆盘从 A移到 C• n>1 时,先把上面 n-1 个圆盘从 A移到B,然后将 n号盘从 A移到 C, 再将 n-1 个盘从B移到 C 。即把求解 n 个圆盘的 Hanoi问题转化为求解 n-1 个圆盘的 Hanoi问题,依次类推,直至转化成只有一个圆盘的 Hanoi问题

• 算法:• 执行情况:

• 递归工作栈保存内容:形参n,x,y,z 和返回地址• 返回地址用行编号表示

n x y z 返回地址

Page 21: 第 3 章  栈和队列

22

main() { int m; printf("Input number of disks”); scanf("%d",&m); printf(”Steps : %3d disks”,m); hanoi(m,'A','B','C');(0) }void hanoi(int n,char x,char y,char z)(1) {(2) if(n==1)(3) move(1,x,z);(4) else{(5) hanoi(n-1,x,z,y);(6) move(n,x,z);(7) hanoi(n-1,y,x,z);(8) }(9) }

A B C

123

3 A B C 0

3 A B C 0

2 A C B 6

3 A B C 0

2 A C B 6

1 A B C 6

A B C

3 A B C 0

2 A C B 6

Page 22: 第 3 章  栈和队列

23

main() { int m; printf("Input the number of disks scanf("%d",&m); printf("The steps to moving %3d hanoi(m,'A','B','C');(0) }void hanoi(int n,char x,char y,char z)(1) {(2) if(n==1)(3) move(1,x,z);(4) else{(5) hanoi(n-1,x,z,y);(6) move(n,x,z);(7) hanoi(n-1,y,x,z);(8) }(9) }

A B C

3 A B C 0

2 A C B 6

1 C A B 8

A B C

3 A B C 0

2 A C B 6

3 A B C 0

3 A B C 0

2 A C B 6

Page 23: 第 3 章  栈和队列

24

main() { int m; printf("Input the number of disks scanf("%d",&m); printf("The steps to moving %3d hanoi(m,'A','B','C');(0) }void hanoi(int n,char x,char y,char z)(1) {(2) if(n==1)(3) move(1,x,z);(4) else{(5) hanoi(n-1,x,z,y);(6) move(n,x,z);(7) hanoi(n-1,y,x,z);(8) }(9) }

A B C

3 A B C 0

2 B A C 8

3 A B C 0

2 B A C 8

1 B C A 6

A B C

3 A B C 0

2 B A C 8

3 A B C 0

Page 24: 第 3 章  栈和队列

25

main() { int m; printf("Input the number of disks scanf("%d",&m); printf("The steps to moving %3d hanoi(m,'A','B','C');(0) }void hanoi(int n,char x,char y,char z)(1) {(2) if(n==1)(3) move(1,x,z);(4) else{(5) hanoi(n-1,x,z,y);(6) move(n,x,z);(7) hanoi(n-1,y,x,z);(8) }(9) }

A B C

3 A B C 0

2 B A C 8

1 A B C 8

A B C

3 A B C 0

2 B A C 8

3 A B C 0

栈空

3 A B C 0

2 B A C 8

Page 25: 第 3 章  栈和队列

26

递归的特性

有限次递归调用,非递归出口 if 或while语句递归的优缺点

优点:结构清晰、易读,正确性易证明

缺点:运行效率低,时空消耗大递归过程的模拟

先写递归算法,再转化成非递归

PASCAL版 英文版 Hanoi 非递归

实质:系统管理的递归工作栈改为程序员管理

Page 26: 第 3 章  栈和队列

27

作业:

3.6

3.7

3.8

补:写一递归算法将单链表 (无头结点 )倒序

Page 27: 第 3 章  栈和队列

28

队列的定义及特点•定义:队列是限定只能在表的一端进行插入,在表的另一端进行删除的线性表 双端• 队尾 (rear)——允许插入的一端• 队头 (front)——允许删除的一端

•队列特点:先进先出 (FIFO)

a1 a2 a3…………………….an 入队出队

front rear队列 Q=(a1,a2,……,an)

•双端队列

a1 a2 a3…………………….an

端 1 端 2

入队出队

入队出队

3.4 队列 (Queue)

Page 28: 第 3 章  栈和队列

29

• 结点定义typedef struct QNode { QElemType data; struct QNode *next;}QNode, *QueuePtr;

头结点

^…...front

队头 队尾

rear设队首、队尾指针 front 和 rear,front 指向头结点, rear 指向队

抽象数据类型定义 QueueEmpty , EnQueue , DeQueue

typedef struct { QueuePtr front;

QueuePtr rear;

} LinkQueue;

链队列 - 队列的链式表示和实现

Page 29: 第 3 章  栈和队列

30

front rear

x 入队 ^x

front rear

y 入队 x ^y

front rear

x 出队 x ^y

front rear

空队 ^

front rear

y 出队 ^

Page 30: 第 3 章  栈和队列

31

•入队算法 EnQueue

•出队算法 DeQueue最后一个元素出队后,队尾指针指向头结点If (Q.rear == p) Q.rear = Q.front;

部分算法描述 P62

• InitQueue• DestroyQueue

Page 31: 第 3 章  栈和队列

32

• 实现:用一维数组实现 sq[M]

front=-1rear=-1

1

2

3

4

5

0队空

1

2

3

4

5

0front J1,J2,J3 入队

J1

J2

J3rear

rear

1

2

3

4

5

0J4,J5,J6 入队

J4

J5

J6

front

设两个指针 front,rear, 约定:rear 指示队尾元素;front 指示队头元素前一位置初值 front=rear=-1

空队列条件: front==rear入队列: sq[++rear]=x;出队列: x=sq[++front];

rear

rear

front

rear

1

2

3

4

5

0J1,J2,J3 出队

J1

J2

J3

front

frontfront

队列的顺序存储结构

Page 32: 第 3 章  栈和队列

33

• 存在问题设数组大小为 M ,则:• 当 front=-1,rear=M-1 时,再有元素入队发生溢出——真溢出• 当 front-1,rear=M-1 时,再有元素入队发生溢出——假溢出

• 解决方案• 队首固定,每次出队剩余元素向下移动——浪费时间• 循环队列

• 基本思想:把队列设想成环形,让 sq[0]接在 sq[M-1]之后,若 rear+1==M, 则令 rear=0;

0

M-1

1

front

rear…...

…...

• 实现:利用“模”运算• 入队: rear=(rear+1)%M; sq[rear]=x;• 出队: front=(front+1)%M; x=sq[front];• 队满、队空判定条件

Page 33: 第 3 章  栈和队列

34

0

12

3

45

rearfront

J4

J5J6

0

12

3

45

rear

front

J9J8

J7

J4

J5J6

0

12

3

45

rear

front

初始状态

J4,J5,J6 出队

J7,J8,J9 入队

队空: front==rear队满: front==rear

解决方案:1.另外设一个标志以区别队空、队满2.少用一个元素空间: 队空: front==rear 队满: (rear+1)%M==front

Page 34: 第 3 章  栈和队列

35

•入队算法: EnQueue(Q.rear + 1) % MAXQSIZE == Q.front 满队

•出队算法: DeQueueQ.front == Q.rear 空队

• InitQueue

• QueueLength

基本操作算法描述 P64

Page 35: 第 3 章  栈和队列

36

队列应用举例 离散事件模拟划分子集问题图的广度优先搜索多任务操作系统中 CPU调度,多队列,分

时使用

Page 36: 第 3 章  栈和队列

37

• 问题描述:已知集合 A={a1,a2,……an} ,及集合上的关系 R={ (ai,aj) | ai,ajA, ij} ,其中 (ai,aj) 表示 ai 与 aj 间存在冲突关系。要求将 A划分成互不相交的子集 A1,A2,……Ak,(kn) ,使任何子集中的元素均无冲突关系,同时要求分子集个数尽可能少

例 A={1,2,3,4,5,6,7,8,9} R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) } 可行的子集划分为: A1={ 1,3,4,8 } A2={ 2,7 } A3={ 5 } A4={ 6,9 }

划分子集问题

Page 37: 第 3 章  栈和队列

38

•算法思想:利用循环筛选。从第一个元素开始,凡与第一个元素无冲突的元素划归一组;再将剩下的元素重新找出互不冲突的划归第二组;直到所有元素进组

•所用数据结构• 冲突关系矩阵

• r[i][j]=1, i,j 有冲突• r[i][j]=0, i,j 无冲突

• 循环队列 cq[n]• 数组 result[n] 存放每个元素分组号• 工作数组 newr[n]

Page 38: 第 3 章  栈和队列

39

•工作过程• 初始状态: A 中元素放于 cq 中, result 和 newr 数组清零,

组号 group=1• 第一个元素出队,将 r矩阵中第一行“ 1”拷入 newr 中对

应位置,这样,凡与第一个元素有冲突的元素在 newr 中对应位置处均为“ 1”, 下一个元素出队• 若其在 newr 中对应位置为“ 1”,有冲突,重新插入

cq 队尾,参加下一次分组• 若其在 newr 中对应位置为“ 0”, 无冲突,可划归本组;

再将 r矩阵中该元素对应行中的“ 1”拷入 newr 中• 如此反复,直到 9 个元素依次出队,由 newr 中为“ 0”的单元对应的元素构成第 1 组 ,将组号 group 值“ 1”写入 result 对应单元中

• 令 group=2,newr清零,对 cq 中元素重复上述操作,直到 cq 中 front==rear,即队空,运算结束

Page 39: 第 3 章  栈和队列

40

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

1 2 3 4 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

f r

0 0 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8

newr

0 0 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

初始

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 40: 第 3 章  栈和队列

41

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 3 4 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

f r

0 1 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8

newr

1 0 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 41: 第 3 章  栈和队列

42

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 3 4 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8

newr

1 0 0 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 42: 第 3 章  栈和队列

43

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 4 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 0 1 1 0 0

0 1 2 3 4 5 6 7 8

newr

1 0 1 0 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 43: 第 3 章  栈和队列

44

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 44: 第 3 章  栈和队列

45

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 45: 第 3 章  栈和队列

46

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 46: 第 3 章  栈和队列

47

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 8 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 0 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 47: 第 3 章  栈和队列

48

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 48: 第 3 章  栈和队列

49

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

2 5 6 7 9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 0 1 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 0 1 1 0 0 0 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 49: 第 3 章  栈和队列

50

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

5 6 7 9

0 1 2 3 4 5 6 7 8 cq

f r

1 0 0 0 1 1 0 1 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 0 0 0 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 50: 第 3 章  栈和队列

51

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

6 7 9 5

0 1 2 3 4 5 6 7 8 cq

f r

1 0 0 0 1 1 0 1 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 0 0 0 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 51: 第 3 章  栈和队列

52

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

7 9 5 6

0 1 2 3 4 5 6 7 8 cq

f r

1 0 0 0 1 1 0 1 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 0 0 0 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 52: 第 3 章  栈和队列

53

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

9 5 6

0 1 2 3 4 5 6 7 8 cq

f r

1 0 1 0 1 1 0 1 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 0 0 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 53: 第 3 章  栈和队列

54

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

5 6 9

0 1 2 3 4 5 6 7 8 cq

f r

1 0 1 0 1 1 0 1 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 0 0 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 54: 第 3 章  栈和队列

55

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

6 9

0 1 2 3 4 5 6 7 8 cq

f r

0 1 0 1 0 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 3 0 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 55: 第 3 章  栈和队列

56

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

9 6

0 1 2 3 4 5 6 7 8 cq

f r

0 1 0 1 0 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 3 0 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 56: 第 3 章  栈和队列

57

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

9 6

0 1 2 3 4 5 6 7 8 cq

fr

0 1 0 1 0 1 1 0 10 1 2 3 4 5 6 7 8

newr

1 2 1 1 3 0 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 57: 第 3 章  栈和队列

58

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

9

0 1 2 3 4 5 6 7 8 cq

fr

0 1 1 0 1 0 1 0 0

0 1 2 3 4 5 6 7 8

newr

1 2 1 1 3 4 2 1 0

0 1 2 3 4 5 6 7 8 result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

Page 58: 第 3 章  栈和队列

59

•算法描述

0 1 0 0 0 0 0 0 0

0 1 0 1 1 0 0 0 0

0 0 0 0 0 1 1 0 00 0 0 0 1 0 0 0 10 1 0 1 0 1 1 0 10 1 1 0 1 0 1 0 00 0 1 0 1 1 0 0 00 1 0 0 0 0 0 0 0

1 0 0 0 1 1 0 1 1

R=

0 1 2 3 4 5 6 7 8 cq

f r

0 1 1 1 1 0 1 0 0

0 1 2 3 4 5 6 7 8

newr

1 2 1 1 3 4 2 1 40 1 2 3 4 5 6 7 8

result

R={ (2,8), (9,4), (2,9), (2,1), (2,5), (6,2), (5,9), (5,6), (5,4), (7,5), (7,6), (3,7), (6,3) }

可行的子集划分为: A1={ 1,3,4,8 } A2={ 2,7 } A3={ 5 } A4={ 6,9 }

Page 59: 第 3 章  栈和队列

60

作业

3.11

3.12