23
Copyright © 2012 yuga 1 11.2 Catenable Double-Ended Queue PFDS #12 @yuga 2012-12-01

PFDS 11.2 catenable double ended queue

Embed Size (px)

DESCRIPTION

SimpleCatenableDeque までです。

Citation preview

Page 1: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 1

11.2

Catenable Double-Ended Queue

PFDS #12

@yuga

2012-12-01

Page 2: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 2

動機

Queueを効率よく連結したい

できればO(1)で

Page 3: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 3

Catenable Deque

連結可能なDequeのシグネチャ

CATENABLEDEQUE :

module type CATENABLEDEQUE = sig type ‘a cat val empty : ‘a cat val isEmpty : ‘a cat -> bool val snoc : ‘a cat * ‘a -> ‘a cat val head : ‘a cat -> ‘a val tail : ‘a cat -> ‘a cat val cons : ‘a * ‘a cat -> ‘a cat val last : ‘a cat -> ‘a val init : ‘a cat -> ‘a cat val (++) : ‘a cat -> ‘a cat -> ‘a cat end

Page 4: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 4

Catenable Deque

連結可能なDequeのシグネチャ

CATENABLEDEQUE :

module type CATENABLEDEQUE = sig type ‘a cat include module DEQUE with type ‘a queue := ‘a cat val (++) : ‘a cat -> ‘a cat -> ‘a cat end

Page 5: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 5

解決の方針

DequeをDequeにいれる (Structural Abstraction)

BootStrapped type SimpleCatenableDeque (初級編)

ImplicitCatenableDeque (上級編)

Primitive type これまでに登場したDeque (ただしImplicitCatenableDequeの実装には

Dequeの要素数を返すsize関数の実装が必要)

※すべての関数がO(1)時間で実行可能であること。

(実時間/償却時間いずれでもよい)

Page 6: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 6

SimpleCatenableDequeの実装

データ構造

SHALLOW … 単体のDeque

DEEP … 連結したDeque

front – middle – rearの3パーツ構成

frontとrearは必ず2個以上の要素を持つ

module SimpleCatenableDeque (D : DEQUE) : CATENABLEDEQUE = struct type ‘a cat = SHALLOW of ‘a D.queue | DEEP of ‘a D.queue (* front *) * ‘a D.queue cat susp (* middle *) * ‘a D.queue (* rear *) …

Page 7: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 7

図解: 実装 (cons)

consやsnocは直接PrimitiveのDequeに要素を入れる。

1 2 0

1 2 3 4

DEEP

front middle rear

D.queue

SHALLOW

‘a

0

Page 8: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 8

実装 (++)

5パターンある。DEEPのmiddleについては再帰的に行う。

1. どちらかが2未満の要素を持つSHALLOW同士の連結

2. どちらも2以上の要素をもつSHALLOW同士の連結

3. DEEPと2未満の要素を持つSHALLOWの連結

4. DEEPと2以上の要素を持つSHALLOWの連結

5. DEEP同士の連結

a. middle:どちらかが2未満の要素を持つSHALLOW同士の連結

b. middle:どちらも2以上の要素をもつSHALLOW同士の連結

c. middle:DEEPと2未満の要素を持つSHALLOWの連結

d. middle:DEEPと2以上の要素を持つSHALLOWの連結

e. middle:DEEP同士の連結

i. middle:…

T(m+n) = T((m – (4 + c))/2) + T((n – (4 + d))/2) + O(1)

= O(min (log(m), log(n)))

Page 9: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 9

図解: 実装 (++)

1. どちらかが2未満の要素を持つSHALLOW同士の連結

1 2 3

1 2 3 ++

D.queue

SHALLOW

‘a

Page 10: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 10

図解: 実装 (++)

2. どちらも2以上の要素をもつSHALLOW同士の連結

1 2 3 4

1 2 3 4

++

DEEP

front middle rear

Page 11: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 11

図解: 実装 (++)

3. DEEPと2未満の要素を持つSHALLOWの連結

1 2 3 4

1 2 3 4 ++

++

5

5

Page 12: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 12

図解: 実装 (++)

5a. DEEPと2以上の要素を持つSHALLOWの連結

1 2 5 6

1 2 3 4 ++

3 4

5 6

Page 13: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 13

図解: 実装 (++)

5a. DEEP同士の連結( middle:どちらかが2未満の要素を持つSHALLOW同士の連結)

1 2 7 8

1 2 3 4 5 6 7 8 ++

3 4

5 6

3 4 5 6 ++

Page 14: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga

14

図解: 実装 (++)

5b. DEEP同士の連結(middle:どちらも2以上の要素をもつSHALLOW同士の連結)

1 2 15 16

1 2 7 8 3 4

5 6

9 10 15 16

11 12

13 14

3 4

5 6

7 8

9 10

11 12

13 14

3 4

5 6

7 8

9 10

11 12

13 14

++

++

Page 15: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga

15

図解: 実装 (++)

5e. DEEP同士の連結(middle:DEEP同士の連結)

1 2 15 16

3 4

5 6

7 8

9 10

11 12

13 14

17 18 31 32

19 20

21 22

23 24

25 26

27 28

29 30

++

3 4

5 6

7 8

9 10

11 12

13 14

15 16

17 18

19 20

21 22

25 26

27 28

29 30

23 24

++

++

9 10

11 12

13 14

15 16

17 18

19 20

21 22

23 24

Page 16: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 16

実装 (tail)

SHALLOWはそのまま。DEEPは先頭を除去後、frontの要素数が2以上になるならそのまま、そうでないならSHALLOWにする。

1. SHALLOWをtail

2. DEEP(frontが3個以上)をtail

3. DEEP(frontが2個、middleが0個)をtail

4. DEEP(frontが2個、middleが1個以上)をtail

Page 17: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 17

図解: 実装 (tail)

1. SHALLOWをtail

1 2 3

1 2 3

Page 18: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 18

図解: 実装 (tail)

2. DEEP(frontが3個以上)をtail

7 8 5 6 3 4 2

7 8 5 6 3 4 2

Page 19: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 19

図解: 実装 (tail)

3. DEEP(frontが2個、middleが0個)をtail

1 2 3 4

1 2 3 1

2 3 4 1

Page 20: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 20

図解: 実装 (tail)

4. DEEP(frontが2個、middleが1個以上)をtail

1 2 7 8

3 4

5 6

1 7 8

3 4

5 6

2

1 7 8

5 6 3 4

2

1 7 8 5 6 3 4 2

Page 21: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 21

Exercise 11.3: tailが償却実行時間O(1)か?

DEEPに、middleのsuspensionを作成するとき、そのmiddleに1 debitを割り当てる。

次にmiddleを操作するときまでに返却しなければならない。

Debit Invariant:

DEEPのdebit数の上限 =

0 if frontが2個 1 if frontが3個以上

tail時に繰り下がり処理のため

middleを操作することになるから

Page 22: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 22

Exercise 11.3: tailが償却実行時間O(1)か?

振り返り(9.2.3 Lazy Representation)

3個以上

2個

繰り下がりを再帰的に行うことでdebitは発生するが、返却が必要なdebitはO(1)

Page 23: PFDS 11.2 catenable double ended queue

Copyright © 2012 yuga 23

Exercise 11.3: tailが償却実行時間O(1)か?

1. SHALLOWをtail

SHALLOWには既存debitが存在しない。

SHALLOWのtail操作では新規debitは発生しない。

2. DEEP(frontが3個以上)をtail

tail前はfrontが3個以上なので、middleにdebitが1割り当てられている。

middleを操作しないので新規debitは発生しない。

tail操作後、frontが2個になる場合:

– debitの許容数は-1。

– したがって合計1debitを返却する。

3. DEEP(frontが2個、middleが0個)をtail

tail前はfrontが2個なので、middleに割り当てられたdebitは0。

middleを破棄するので新規debitは発生しない。

tail後、SHALLOWになりdebit許容数が-1。

4. DEEP(frontが2個、middleが1個以上)をtail

tail前はfrontが2なので、middleに割り当てられたdebitは0。

middleの操作でsuspensionを作成しているので、middleに新規debitが1発生する。

tail後はfrontは3個以上なので、debit許容数は+1

したがってO(1)