bst - feusci.feu.ac.th/faa/dsa/bookpdfs/chap7-selfbalancedbst.pdfself-balanced binary search trees...

52
Self-Balanced Binary Search Tree เป็ น BST ชนิดหนึ่งที่มีการปรับความสูงของ tree ให ้มี ความสูงน ้อยที่สุดเพื่อให ้การเข ้าหาข ้อมูลเป็ นไปอย่างง่ายและรวดเร็วขึ้น และความสูงดังกล่าวจะ เป็ นความสูงที่เกิดขึ้นจากความสัมพันธ์กับจานวนของ node ที่มีอยู่ใน BST ซึ่งการปรับความสูง (หรืออาจเรียกว่า ความสมดุล) นี้จะกระทาโดยอัตโนมัติหลังจากการเข ้าหาข ้อมูล หลังจากจบบทเรียนนี้แล ้ว ผู ้อ่านจะได ้ทราบถึง o โครงสร ้างและข ้อกาหนดของ AVL tree o การนาข ้อมูลเข ้า (หรือออกจาก) AVL tree และการปรับความสูง o โครงสร ้างและข ้อกาหนดของ Red-Black tree o การนาข ้อมูลเข ้า (หรือออกจาก) Red-Black tree และการปรับความสูง o โครงสร ้างและข ้อกาหนดของ Splay tree o การนาข ้อมูลเข ้า (หรือออกจาก) Splay tree และการปรับความสูง 7.1 AVL Tree การนาข ้อมูลเข ้า การลบข ้อมูล และการค ้นหาข ้อมูลใน BST จะใช ้เวลาน้อยมาก (มีประสิทธิภาพ สูง หรือที่เรียกว่าการใช ้เวลาแบบ sub-linear running time) ถ้า node ต่าง ๆ ที่อยู่ใน tree อยูในสภาพที่กระจายออกไปจาก root (ทั้งสองข ้าง) ซึ่งลักษณะดังกล่าวทาให ้การค ้นหา node ใน BST นั้นไวขึ้น ผู ้อ่านอย่าลืมว่าปัจจัยของการค ้นหา node ใน tree นั้นส่วนหนึ่งก็คือความสูงของ tree ยิ่งมีความสูงมากการค ้นหาก็ใช ้เวลามาก ภาพที7.1 ความสูงที่ไม่เหมาะสมกับจานวน node ที่มีอยู่ใน BST (ตัวเลขข ้าง node หมายถึงระดับความสูง) 34 24 14 45 76 89 82 18 92 99 0 1 2 3 4 0 1 2 0 0 8 12 14 18 20 1 2 3 4 0

Upload: others

Post on 21-Aug-2020

1 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Tree เปน BST ชนดหนงทมการปรบความสงของ tree ใหมความสงนอยทสดเพอใหการเขาหาขอมลเปนไปอยางงายและรวดเรวขน และความสงดงกลาวจะเปนความสงทเกดข นจากความสมพนธกบจ านวนของ node ทมอยใน BST ซงการปรบความสง (หรออาจเรยกวา ความสมดล) นจะกระท าโดยอตโนมตหลงจากการเขาหาขอมล หลงจากจบบทเรยนนแลว ผอานจะไดทราบถง o โครงสรางและขอก าหนดของ AVL tree o การน าขอมลเขา (หรอออกจาก) AVL tree และการปรบความสง o โครงสรางและขอก าหนดของ Red-Black tree o การน าขอมลเขา (หรอออกจาก) Red-Black tree และการปรบความสง o โครงสรางและขอก าหนดของ Splay tree o การน าขอมลเขา (หรอออกจาก) Splay tree และการปรบความสง 7.1 AVL Tree การน าขอมลเขา การลบขอมล และการคนหาขอมลใน BST จะใชเวลานอยมาก (มประสทธภาพสง หรอทเรยกวาการใชเวลาแบบ sub-linear running time) ถา node ตาง ๆ ทอยใน tree อยในสภาพทกระจายออกไปจาก root (ทงสองขาง) ซงลกษณะดงกลาวท าใหการคนหา node ใน BST นนไวขน ผอานอยาลมวาปจจยของการคนหา node ใน tree นนสวนหนงกคอความสงของ tree ยงมความสงมากการคนหากใชเวลามาก

ภาพท 7.1 ความสงทไมเหมาะสมกบจ านวน node ทมอยใน BST (ตวเลขขาง node หมายถงระดบความสง)

34

24

14 45

76

89

82 18 92

99

0

1

2

3

4

0

1

2

0

0

8

12

14

18

20

1

2

3

4

0

Page 2: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

178

ภาพท 7.2 ความสงทเหมาะสมกบจ านวน node ทมอยใน BST

การทจะท าให BST ใชเวลาในการประมวลผลในระดบดนน เราตองท าใหการประมวลผลใชเวลาเทากบ log2 n (โดยท n คอจ านวน node ใน tree) ซงสามารถท าไดดวยการก าหนดให ความสมพนธของ node และความสงอยในรปของคาทใกลเคยงกบ log2 n ซงท าไดดวยการใช

คา floor ของ log2 n และคา floor ของเลขใด ๆ (x) กคอ integer ทใหญทสดทนอยกวา x เชน คา floor ของ 7.345 กคอ 7 คา floor ของ 3.1415926 กคอ 3 หรอพดงายๆ กคอ คา floor ของ integer ทเปนบวกกคอคาทถกตดทศนยมออก (truncating) จากภาพของ BST ทงสามตวในภาพท 7.1 และ 7.2 นน BST ในภาพท 7.2 เปน tree ทมความสงทดทสดเมอเปรยบเทยบอตราสวนของจ านวนของ node กบความสง ในทางคณตศาสตรเราร วา logab = y สามารถเขยนไดอกแบบคอ ay = b เพราะฉะนน BST ทางซายของภาพท 7.1 ม node = 10 ความสงเทากบ 4 นนไมใช tree ทเหมาะสมเพราะ log2 10 = 3.3219 ซงเมอหาคา floor แลวเราได 3 แตความสงจรงของ tree เทากบ 4 สวน tree ทางดานขวาของภาพเดยวกน log2 5 ~ 2 เปนความสงทเราตองการแตความสงจรงเปน 4 ส าหรบ tree ในภาพท 7.2 นนเปน tree ทเหมาะสมทงนเพราะ log2 8 = 3 (23 = 8) และความสงของ tree กเทากบสาม ดงนนถาเราตองการใหการเขาหาขอมลไวขนเราตองหาวธการทจะท าใหอตราสวนของจ านวนของ node และความสงใน tree มความสมดลกน (คาใกลเคยงกบ log2 n) วธการทจะใหไดมาซงความสมดลของ BST มหลายวธ วธการแรกทเราจะมาดกนคอวธการของ AVL tree AVL Tree ตงชอตามผสราง คอ Adelson-Velskii, และ Landis ในป ค.ศ. 1962 เปน BST ทปรบความสมดลดวยการก าหนดความสงของ sub-tree ทงสองขางใหมความแตกตางกนไมเกน 1 ความสง (ดภาพท 7.3)

34

24

14 45

76

89

37

0

2

3

0

0

1

1

Page 3: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

179

ภาพท 7.3 AVL tree ทมความสมดล1

tree ทม node 23 เปน root มความสงของ tree ทางดานซาย (HL = height of left) มคาเทากบ 3 ความสงของ tree ทางดานขวา (HR = height of right) มคาเทากบ 2 ท าใหคาความแตกตางของความสงมคาเทากบ 1 ซงเปนคาทท าให tree ของเรานมการ balance ของ node สวน sub-tree ทม node 18 เปน root มความสงทางดานซายเทากบ 2 และ ความสงทางดานขวามคาเทากบ 1 ท าใหคาความแตกตางมคาเปน 1 ซงท าใหเกดความ balance ของ node

สวน sub-tree ทม node 44 เปน root มความสงทางดานซายเทากบ 0 และ ความสงทางดานขวาเทากบ 1 ท าใหคาความแตกตางมคาเปน 1 ซงท าใหเกดความ balance ของ node

เพราะฉะนนเราสามารถสรปไดวา ถา 1 HRHL เรากจะม tree ทเรยกวา AVL tree หรอ

พดงาย ๆ วา ถา tree มคาความสงของแตละระดบไมเกน 1 เราเรยก tree นวา AVL tree การทจะท าให tree มความ balance นนเราจ าเปนทจะตองวางขอก าหนดของการน า node เขา

ส tree ดวยการตรวจสอบวา node ทจะน าเขาส tree นนท าให tree เกดความสมดลหรอไม ถาไม เรากตองท าการปรบความสง ซงสามารถท าไดดวยการหมน (rotate) node ไปทางดานซาย หรอ ทางขวา โดยทวไป algorithm ตาง ๆ ท นกวทยาศาสตรทางดาน computer ไดคดคนข นมา มกจะปลอยใหการน าขอมลเขาเปนไปตามธรรมชาตของ การน าขอมลเขาของ BST แตทแตกตางออกไปกคอ จะคอยตรวจสอบถงความ balance ของ tree ทเกดข นหลงจากการน าขอมลเขาเสมอ และจะแกไขความไม balance ของ tree หรอ sub-tree นน ๆ ทนท

1 จะเรยกวาการ balance ของ node สลบกบการเรยกวาความสมดล

44

23

18

12 20

8 14

52

HL = 3 HR = 2

Page 4: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

180

7.1.1 ความไมสมดลของ node และ การหมน node เพอใหเกดความสมดล ในการน า node เขาส (insert) หรอดงออก (delete) ของ AVL tree นนอาจท าใหโครงสรางของ AVL tree ผดไปจากขอก าหนด (ความสงตางกนมากกวาหนง) ซงกระบวนการทท าใหเกดความไมสมดลนมอย 4 ลกษณะดงน กรณท 1: การ insert ทางดานซายของ node ทอยทางดานซายของ tree (left of left) [น าขอมลเขาส sub-tree ทางซายของลกทอยทางซายของ Node X]

ภาพท 7.4 ตองการ insert node 4 เขาส tree ภาพท 7.5 tree ไม balance หลงจากการ insert

กรณท 2: การ insert ทางดานขวาของ node ทอยทางดานขวาของ tree (right of right)

[น าขอมลเขาส sub-tree ทางขวาของลกทอยทางขวาของ Node X]

ภาพท 7.6 ตองการ insert node 44 เขาส tree ภาพท 7.7 tree ไม balance หลงจากการ insert

Node X

ลกทางซายของ Node X

18

12 20

8 14

4

เกดความไม balance ท node

18

18

12 20

8 14

4

น า node 4 เขาทางดานซายของลกของ

Node X

น า node 14 เขาทางดานขวาของลกของ node X

ลกทางขวาของ Node X

Node X 14

12 20

18 23

44

เกดความไม balance ท node

14

14

12 20

18 23

44

Page 5: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

181

กรณท 3: การ insert ทางดานขวาของ node ทอยทางดานซายของ tree (right of left) [น าขอมลเขาส sub-tree ทางขวาของลกทอยทางซายของ Node X]

ภาพท 7.8 ตองการ insert node 13 ภาพท 7.9 tree ไม balance หลงจากการ insert

กรณท 4:

การ insert ทางดานซายของ node ทอยทางดานขวาของ tree (left of right) [น าขอมลเขาส sub-tree ทางซายของลกทอยทางขวาของ Node X]

ภาพท 7.10 ตองการ insert node 19 ภาพท 7.11 tree ไม balance หลงจากการ insert

เรารแลววาเมอเกดความไม balance ใน tree เราจะตองท าการหมน node ตาง ๆ เพอใหไดมาซงความ balance นน การหมนนนเราจะหมนในลกษณะของ การหมนครงเดยว หรอ หมนสองครง ทงนข นอยกบลกษณะของ tree วามความซบซอนเพยงใด โดยทวไปการหมนสองครงจะเปนการหมนไปในทศทางตรงกนขามกน คออาจเปนการหมนซายหนงครงแลวกหมนขวา หรอหมนขวาหนงครงแลวจงหมนซาย ลองมาดการหมนแบบตาง ๆ กน

ลกทางขวาของลกของ Node X

ลกของ Node X

Node X เกดความไม balance ท node

18

18

12 20

8 14

13

18

12 20

8 14

13

node 13 จะตองถกน าเขาทางดานขวาของ node 12

ลกทางขวาของ

Node X

Node X เกดความไม

balance ท node 14

14

12 20

44 18

19

14

12 20

44 18

19

node 19 ตองถกน าเขาทางดานซายของ Node 20

Page 6: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

182

การแกไขของกรณท 1 (และ 2): หมนขวา (rotate right) เมอเกดการไม balance ทางดานซายของ (left of left) tree

ภาพท 7.12 หลงจาก insert 12 – tree ไม balance ภาพท 7.13 หลงจากการหมนขวา

ภาพท 7.14 หลงจาก insert 4 – tree ไม balance ภาพท 7.15 หลงจากการหมนขวา

ในการหมนซาย (กรณท 2) ครงเดยวนนกท าคลาย ๆ กบ การหมนขวาทแสดงใหเหนจากภาพดานบนน ตางกนเพยงแคทศทางของการหมน (Symmetric rotation)

A

A

tmp

18

12 20

20

18

12

X

X

tmp

B

C

X tmp

B C

A

A

18

12 20

14 8

4

12

8 18

14 4 20

tmp X

Page 7: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

183

การแกไขของกรณท 3 (และ 4): หมนซาย 1 คร งหลงจากน นกหมนขวาอก 1 คร ง (right of left)

ภาพท 7.16 การหมนสองครง (double rotate right) อยางงาย

ภาพท 7.17 tree ทไม balance ท าใหเราตองหมนซาย node 12

12

4

8

12

8

4

8

4 12

node 8 ท าให tree ไม balance

หลงจากหมน node 4

หลงจากหมน node 12

23

18 44

12 20

4

52

14

16

node 16 ท าให tree ไม

balance เราตองหมน node 12 ไปทางซาย 1 ครง

Page 8: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

184

ภาพท 7.18 การหมนครงทสอง (ของ node 18)

ภาพท 7.19 tree หลงจากการหมนครงทสอง ซงท าให tree มความ balance

ในการหมนเพอแกไขความไม balance ของกรณท 4 กเชนเดยวกนกบกรณท 3 ตางกนททศทางของการหมนเทานนเอง

23

18 44

14 20

12

52

16

4

Subtree ทเราได หลงจากการหมนซาย

ของ node 12 กอนหนาน

Tree ยงไม balance เราตองหมน node 18 ไปทางขวา

อก 1 ครง

23

14 44

12 18

4

52

16 20

Page 9: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

185

7.1.2 การน า node เขาส AVL tree ในการน าขอมลเขาส AVL tree นนเราเรมดวยการตรวจสอบวา tree มขอมลหรอไม ถามเรากหาต าแหนงทเหมาะสมในการใส node ดวยการเปรยบเทยบวา ขอมลทจะน าเขามากหรอนอยกวาขอมลทอยใน node นน ถานอยกวาเรากไปทางซาย ถามากกวาเรากไปทางขวา และเมอเรามาถงต าแหนงทเหมาะสม เรากท าการน าขอมลเขาพรอมทงตรวจสอบความสมดลของ tree ถาไมสมดลเรากท าการหมน node ตามทศทางของการน าเขา ซงถาเราน าขอมลเขาทางดานซาย tree ทางซายนอาจสงเกนไป เรากท าการหมน node เพอสรางความสมดลใหกบ tree น (และเรากจะท าในลกษณะเดยวกน ถาการน าเขานนเกดทางดานขวา) ทงนการน าขอมลเขาส tree ของเรานน เราจะไมยอมใหมการน าขอมลทซ ากนเขาส tree เปนอนขาด การเขยน code ของการ insert ขอมลเขาส AVL tree นน เราจะใชเทคนคของ recursion เขามาชวยเหมอนกบทเราท ากบการ insert ของ BST แตจะเพมการตรวจสอบความไม balance ของ tree หลงจากการ insert ทนท //insert into AVL tree

public void insert(T key) {

root = insert(key, root);

}

//internal method to insert key into AVL tree

private AVLNode<T> insert(T key, AVLNode<T> node) {

//tree is empty, just insert

if(node == null) {

node = new AVLNode<T>(key);

}

//key is less than item, so we go left

else if(key.compareTo(node.item) < 0) {

node.left = insert(key, node.left);

if(node.left != null) {

//height is not balance,perform rotation

if((height(node.left) - height(node.right)) == 2) {

if(key.compareTo(node.left.item) < 0)

node = singleRotateRight(node);

else

node = doubleRotateRight(node);

}

}

}

//key is greater than item, so we go right

else if(key.compareTo(node.item) > 0) {

node.right = insert(key, node.right);

if(node.right != null) {

//height is not balance, perform rotation

if((height(node.right) - height(node.left)) == 2) {

if(key.compareTo(node.right.item) > 0)

node = singleRotateLeft(node);

else

node = doubleRotateLeft(node);

}

}

}

else ; //duplicates not allow!

return node;

}

การน า node ใหมเขาส AVL tree นนมขนตอนหลก ๆ อยสองขนตอนคอ 1) น า node เขาส tree ดวยเงอนไขและขอก าหนดของ BST นนคอ node ใหมจะถกน าเขาท leaf node ในต าแหนงทเหมาะสม และเมอ node ใหมถกน าเขาแลว คณสมบตของ AVL tree อาจผดไป ณ ต าแหนงใดต าแหนงหนงจากเสนทางของ root ไปยงต าแหนงใหมของ node ทถกน าเขา 2) เมอเงอนไขของ AVL tree ผดไปเราตองท าการปรบปรง tree ดวยการยอนกลบขนไปยง root

จาก node ใหมทน าเขาพรอมกบตรวจสอบความผดปกตดงกลาว ถาความสงของ sub-tree ทางซายและขวาใด ๆ มความสงเกนหนง เรากท าการหมน node ตาง ๆ เพอปรบปรง tree ให เปนไปตามเงอนไขทไดก าหนดไว

Page 10: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

186

สมมตวาเราตองน า node ใหมเขาทางดานขวา code ทเราตองเรยกกคอ node.right = insert(key, node.right); ซงในทสด (ไปจนสดทางแลว – กลบออกมาจากการเรยกของ recursion) เราจะมาอยท leaf node ของ tree ทางขวา ณ ทนเราจะท าการตรวจสอบความสงของ sub-tree ทงสองขางวาผดเงอนไขหรอไม ถาผดเราจะท าการหมน node ซงอาจเปนการหมนไปทางซายหนงครง หรออาจเปนการหมนสองครง ทงนกข นอยกบผลลพธของการเปรยบเทยบทเกดข น

การปรบดวยการหมนเพอท าใหเกดความสมดลของกรณตาง ๆ ทไดกลาวไว (1 – 4) ม method ส าหรบชวยดงน //LEFT-OF-LEFT

//insert in the left subtree of the left child of X

//do a single rotation with left child (rotate right)

//e.g. insert the followings 20, 18, and 12

private AVLNode<T> singleRotateRight(AVLNode<T> X) {

AVLNode<T> tmp = new AVLNode<T>();

tmp = X.left;

X.left = tmp.right;

tmp.right = X;

return tmp;

}

//RIGHT-OF-RIGHT

//insert in the right subtree of the right child of X

//do a single rotation with right child (rotate left)

//e.g. insert the followings 12, 18, and 20

private AVLNode<T> singleRotateLeft(AVLNode<T> X) {

AVLNode<T> tmp = new AVLNode<T>();

tmp = X.right;

X.right = tmp.left;

tmp.left = X;

return tmp;

}

//RIGHT-OF-LEFT

//insert in the right subtree of the left child of X

//do a single rotation on left child, then rotate right on X

//e.g. insert the followings 12, 4, and 8

private AVLNode<T> doubleRotateRight(AVLNode<T> X) {

X.left = singleRotateLeft(X.left);

return singleRotateRight(X);

}

//LEFT-OF-RIGHT

//insert in the left subtree of the right child of X

//do a single rotation on right child, then rotate left on X

//e.g. insert the followings 12, 44, and 18

private AVLNode<T> doubleRotateLeft(AVLNode<T> X) {

X.right = singleRotateRight(X.right);

return singleRotateLeft(X);

}

7.1.3 การลบ node ออกจาก AVL tree

ส าหรบการลบ node ออกจาก AVL tree นนกท าคลาย ๆ กบการลบ node ออกจาก BST เพยงแตวาในการลบนนเราจะตองตรวจสอบความสมดลของ tree วายงมอยหรอไม ซงวธการกคลายกบการน าขอมลเขา เราจะปรบความสมดลหลงจากทเราลบ node ออกจาก tree เพอใหการลบ node มเสถยรภาพ (stable – ลบแลวโครงสรางใหมยงถกตองตามขอก าหนดของ AVL tree) เราจงก าหนดใหมตวแปรสองตว lastNode และ deleteNode เปนตวท าหนาทในการจ า node ทมการเขาถงระหวางการคนหา node ทตองการลบโดยท lastNode จะเปนตว

เกบ node ทเราไดท าการเขาหาครงสดทาย และ deleteNode จะเปนตวเกบ node ทเราตองการจะลบ //delete node with given key from AVL tree

//replace deleted node with the minimum

Page 11: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

187

//node on its right subtree

public void delete(T key) {

lastNode = null;

deleteNode = null;

root = delete(key, root);

}

//internal method to delete node with given key

//uses inorder successor as replacement node

private AVLNode<T> delete(T key, AVLNode<T> node) {

//tree is empty, cannot delete

if(node == null) {

return null;

}

lastNode = node; //last node seen

//key to delete is on the left

if(key.compareTo(node.item) < 0)

node.left = delete(key, node.left);

//key is on the right

else {

deleteNode = node; //potential node to delete

node.right = delete(key, node.right);

}

//returning from the calls

if(node == lastNode) {

//make sure its our target node

if(deleteNode != null && key.equals(deleteNode.item)) {

//node is rightmost in its subtree

if(deleteNode == lastNode) {

//return left subtree

node = node.left;

}

//node is not rightmost, replace deleted node

//with minimum node on the right subtree

else {

//swap data

T tmp = deleteNode.item;

deleteNode.item = lastNode.item;

lastNode.item = tmp;

//return right subtree

node = node.right;

}

}

}

//adjust the nodes

else {

//left tree is taller than right tree

if((height(node.left) - height(node.right)) == 2) {

if(key.compareTo(node.left.item) < 0)

node = singleRotateRight(node);

else

node = doubleRotateRight(node);

}

//right tree is taller than left tree

if((height(node.right) - height(node.left)) == 2) {

if(key.compareTo(node.right.item) > 0)

node = singleRotateLeft(node);

else

node = doubleRotateLeft(node);

}

}

return node;

}

สมมตวาเราน าขอมล [8, 12, 14, 18, 20, 23, 33, 44, 48, 50, 52] เขาส tree เรากจะได tree ดงทเหนในภาพท 7.20 และสมมตตอไปวาเราตองการทจะลบ node 44 ออกจาก tree สงทเกดข นคอ เราจะเดนเขาหา tree ทางดานขวาจนกวาจะเจอ node 44 ในระหวางทางเราจะจ าคาของ lastNode และ deleteNode ไว ขนตอนทเกดข นไดถกจ าลองไวดงน โดยทครงแรก node ทสงเขาไปมคาเทากบ 18 (root node ของ tree)

Page 12: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

188

1. lastNode = 18, เดนลงทางขวา 2. ก าหนดให deleteNode = lastNode (18), เดนลงทางขวาอก 3. เจอ node 44 จงก าหนดให lastNode = 44, เดนลงทางขวาอก 4. ก าหนดให deleteNode = lastNode (44), เดนลงทางขวาอก 5. เจอ node 50 จงก าหนดให lastNode = 50, เปลยนการเดนไปเปนทางซาย 6. เจอ node 48 จงก าหนดให lastNode = 48, เดนลงทางซายอก 7. เจอ null จงยอนกลบจาก recursion ณ เวลาน lastNode มคาเทากบ node แตคาของ

deleteNode และ lastNode ไมเทากนดงนนเราจงท าการสลบคาของ node ทงสอง แลวจงยอนกลบออกจาก method delete()

ซงผลทเราไดเมอเสรจส นการเรยกแลวท าให node 44 ทเราตองการลบมคาเปน 48 ซงเปนการแทน node ทลบออกดวยคาทนอยทสดทางดานขวาของ node ทตองการลบ ทศทางของการเดนเขาหา tree ไมวาจะเปนทางซาย หรอทางขวาขนอยกบคาของ node ทเจอ ณ เวลานน ซงเกดจากการเปรยบเทยบของประโยค //key to delete is on the left

if(key.compareTo(node.item) < 0)

node.left = delete(key, node.left);

//key is on the right

else {

deleteNode = node; //potential node to delete

node.right = delete(key, node.right);

}

ภาพท 7.20 AVL tree ทสรางจากโปรแกรมตวอยาง

18

12 44

8 14

33

23

20 52

50

48

lastNode

deleteNode

ทศทางการเดนของ

lastNode และคาทเปลยนไป คอ 18, 44, 50, และ 48

deleteNode จะหยดการเปลยนคาเมอมาถง node 44

Page 13: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

189

ภาพท 7.21 AVL tree หลงจากการลบ node 44

เพอใหเกดความเขาใจยงข นในเรองของการหมน node เราจะน าขอมล 21 และ 98 เขาส tree ในภาพท 7.21 ซงท าใหเราไดภาพของ tree ตามล าดบดงน

ภาพท 7.22 การน า node 21 เขาส tree ท าให tree ไม balance

18

12 48

8 14

33

23

20 52

50

การน า node 21 เขาส tree ท าใหเกดความไมสมดล (กรณท 4: left of

right)

18

12 48

8 14

33

23

20 52

50

21

ท าใหเราตองหมน node 48

Page 14: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

190

ภาพท 7.23 tree หลงจากการหมน node 48 ยงไมมความสมดล

ภาพท 7.24 tree หลงจากการหมน node 18 เกดความสมดลของ tree

หลงจากการหมน node 48 tree กยงไมมความสมดล เรา

ตองหมน node 18 ไปทางซาย

อกครง

18

12 23

8 14

21

20

33 50

48

52

23

18 48

12 20

8

33

14 52

50

21

Page 15: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

191

ภาพท 7.25 tree หลงจากการ insert 98

ผอานควรทดลองการน าขอมลเขา และออกจาก AVL tree ดวยขอมลตาง ๆ เพอท าความเขาใจกบการท างานของการน าขอมล และการน าขอมล รวมไปถงการหมน node ในกรณตาง ๆ เพอให เกดความเขาใจมากยงข น เราไดรวบรวม code ทงหมดของ AVLNode.java และ AVLTree.java มาไวใหผอานอกครงหนง

1: /**

2: Structure of node for AVL tree

3: */

4:

5: public class AVLNode<T extends Comparable> {

6: protected T item;

7: protected AVLNode<T> left, right;

8: protected int height;

9:

10: //for empty node

11: AVLNode() {

12: item = null;

13: left = right = null;

14: height = 0;

15: }

16:

17: //for node with item assigned

18: AVLNode(T item) {

19: this.item = item;

subtree ทไมมความ balance หลงจากการใส node 98 เราตองท า

การหมน node 50 ไปทางซายหนง

ครง

subtree หลงจากการหมน node 50

23

18 48

12 20

8

33

14 52

50

21

98

50

52

48

98

33

Page 16: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

192

20: left = right = null;

21: height = 0;

22: }

23:

24: //calculate number of nodes, recursively

25: public int size(AVLNode<T> t) {

26: if(t == null)

27: return 0;

28: else

29: return size(t.left) + size(t.right) + 1;

30: }

31:

32: //print data of node in Pre-order fashion

33: public void preorderPrint() {

34: System.out.print(item + " ");

35: if(left != null) {

36: left.preorderPrint();

37: }

38: if(right != null) {

39: right.preorderPrint();

40: }

41: }

42:

43: //print data of node in In-order fashion

44: public void inorderPrint() {

45: if(left != null) {

46: left.inorderPrint();

47: }

48: System.out.print(item + " ");

49: if(right != null) {

50: right.inorderPrint();

51: }

52: }

53:

54: //print data of node in Post-order fashion

55: public void postorderPrint() {

56: if(left != null) {

57: left.postorderPrint();

58: }

59: if(right != null) {

60: right.postorderPrint();

61: }

62: System.out.print(item + " ");

63: }

64: }

1: /**

2: Structure for AVL Tree

3: Using AVLNode as storage

4: */

5:

6: class AVLTree<T extends Comparable<? super T>> {

7: protected AVLNode<T> root;

8: private AVLNode<T> lastNode; //used in delete(T key)

9: private AVLNode<T> deleteNode; //same

10: private int count = 0;

11:

12: //default constructor

13: AVLTree() {

14: root = null;

15: }

16:

17: //returning height of AVL tree

18: public int height(AVLNode<T> t) {

19: if(t == null)

20: return -1;

21: else

22: return Math.max(height(t.left), height(t.right)) + 1;

23: }

24:

25: //insert into AVL tree

26: public void insert(T key) {

27: root = insert(key, root);

28: }

Page 17: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

193

29:

30: //internal method to insert key into AVL tree

31: private AVLNode<T> insert(T key, AVLNode<T> node) {

32: //tree is empty, just insert

33: if(node == null) {

34: node = new AVLNode<T>(key);

35: }

36: //key is less than item, so we go left

37: else if(key.compareTo(node.item) < 0) {

38: node.left = insert(key, node.left);

39: if(node.left != null) {

40: //height is not balance,perform rotation

41: if((height(node.left) – height(node.right)) == 2) {

42: if(key.compareTo(node.left.item) < 0)

43: node = singleRotateRight(node);

44: else

45: node = doubleRotateRight(node);

46: }

47: }

48: }

49: //key is greater than item, so we go right

50: else if(key.compareTo(node.item) > 0) {

51: node.right = insert(key, node.right);

52: if(node.right != null) {

53: //height is not balance, perform rotation

54: if((height(node.right) – height(node.left)) == 2) {

55: if(key.compareTo(node.right.item) > 0)

56: node = singleRotateLeft(node);

57: else

58: node = doubleRotateLeft(node);

59: }

60: }

61: }

62: else ; //duplicates not allow!

63:

64: return node;

65: }

66:

67: //delete node with given key from AVL tree

68: //replace deleted node with the minimum

69: //node on its right subtree

70: public void delete(T key) {

71: lastNode = null;

72: deleteNode = null;

73: root = delete(key, root);

74: }

75:

76: //internal method to delete node with given key

77: //uses inorder predecessor as replacement node

78: private AVLNode<T> delete(T key, AVLNode<T> node) {

79: //tree is empty, cannot delete

80: if(node == null) {

81: return null;

82: }

83: lastNode = node; //last node seen

84:

85: //key to delete is on the left

86: if(key.compareTo(node.item) < 0)

87: node.left = delete(key, node.left);

88: //key is on the right

89: else {

90: deleteNode = node; //potential node to delete

91: node.right = delete(key, node.right);

92: }

93:

94: //returning from the calls

95: if(node == lastNode) {

96: //make sure its our target node

97: if(deleteNode != null && key.equals(deleteNode.item)) {

98: //node is rightmost in its subtree

99: if(deleteNode == lastNode) {

100: //return left subtree

101: node = node.left;

102: }

Page 18: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

194

103: //node is not rightmost, replace deleted node

104: //with minimum node on the right subtree

105: else {

106: //swap data

107: T tmp = deleteNode.item;

108: deleteNode.item = lastNode.item;

109: lastNode.item = tmp;

110: //return right subtree

111: node = node.right;

112: }

113: }

114: }

115: //adjust the nodes

116: else {

117: //left tree is taller than right tree

118: if((height(node.left) - height(node.right)) == 2) {

119: if(key.compareTo(node.left.item) < 0)

120: node = singleRotateRight(node);

121: else

122: node = doubleRotateRight(node);

123: }

124: //right tree is taller than left tree

125: if((height(node.right) - height(node.left)) == 2) {

126: if(key.compareTo(node.right.item) > 0)

127: node = singleRotateLeft(node);

128: else

129: node = doubleRotateLeft(node);

130: }

131: }

132: return node;

133: }

134:

135: //LEFT-OF-LEFT

136: //insert in the left subtree of the left child of X

137: //do a single rotation with left child (rotate right)

138: //e.g. insert the followings 20, 18, and 12

139: private AVLNode<T> singleRotateRight(AVLNode<T> X) {

140: AVLNode<T> tmp = new AVLNode<T>();

141: tmp = X.left;

142: X.left = tmp.right;

143: tmp.right = X;

144:

145: return tmp;

146: }

147:

148: //RIGHT-OF-RIGHT

149: //insert in the right subtree of the right child of X

150: //do a single rotation with right child (rotate left)

151: //e.g. insert the followings 12, 18, and 20

152: private AVLNode<T> singleRotateLeft(AVLNode<T> X) {

153: AVLNode<T> tmp = new AVLNode<T>();

154: tmp = X.right;

155: X.right = tmp.left;

156: tmp.left = X;

157:

158: return tmp;

159: }

160:

161: //RIGHT-OF-LEFT

162: //insert in the right subtree of the left child of X

163: //do single rotation on left child, then rotate right on X

164: //e.g. insert the followings 12, 4, and 8

165: private AVLNode<T> doubleRotateRight(AVLNode<T> X) {

166: X.left = singleRotateLeft(X.left);

167: return singleRotateRight(X);

168: }

169:

170: //LEFT-OF-RIGHT

171: //insert in the left subtree of the right child of X

172: //do single rotation on right child, then rotate left on X

173: //e.g. insert the followings 12, 44, and 18

174: private AVLNode<T> doubleRotateLeft(AVLNode<T> X) {

175: X.right = singleRotateRight(X.right);

176: return singleRotateLeft(X);

Page 19: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

195

177: }

178:

179: //locate minimum node

180: public T findMin(AVLNode<T> node) {

181: if(node != null) {

182: while(node.left != null)

183: node = node.left;

184: }

185: return node == null ? null : node.item;

186: }

187:

188: //locate maximum node

189: public T findMax(AVLNode<T> node) {

190: if(node != null) {

191: while(node.right != null)

192: node = node.right;

193: }

194: return node == null ? null : node.item;

195: }

196:

197: //remove minimum node

198: private AVLNode<T> removeMin(AVLNode<T> node) {

199: if(node == null) {

200: System.out.println("ERROR! tree is empty.");

201: return null;

202: }

203: else if(node.left != null) {

204: node.left = removeMin(node.left);

205: return node;

206: }

207: else

208: return node.right;

209: }

210:

211: //remove maximum node

212: private AVLNode<T> removeMax(AVLNode<T> node) {

213: if(node == null) {

214: System.out.println("ERROR! tree is empty.");

215: return null;

216: }

217: else if(node.right != null) {

218: node.right = removeMax(node.right);

219: return node;

220: }

221: else

222: return node.left;

223: }

224:

225: //print tree in pre-order fashion

226: public void printAVLTree() {

227: System.out.print("Items: ");

228: root.preorderPrint();

229: System.out.println();

230: }

231: }

โปรแกรมทดสอบการท างานของ AVL tree 1: /**

2: Testing AVL Tree

3: */

4:

5: class TestAVLTree {

6: public static void main(String[] args) {

7: AVLTree<Integer> tree = new AVLTree<Integer>();

8: int []data = {8, 12, 14, 18, 20, 23, 33, 44, 48, 50, 52};

9:

10: //populate tree with data

11: for(int i = 0; i < data.length; i++) {

12: tree.insert(data[i]);

13: }

14: tree.printAVLTree();

15:

Page 20: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

196

16: //delete 44 and insert 21 and 98

17: tree.delete(44);

18: tree.printAVLTree();

19: tree.insert(21);

20: tree.printAVLTree();

21: tree.insert(98);

22: tree.printAVLTree();

23: }

24: }

ผอานควรทดสอบการท างานของ AVL Tree ดวยขอมลตาง ๆ กนในการน าขอมลเขา และการดงขอมลออก เพอใหเกดความเขาใจถงการท างานอยางแทจรง โดยเฉพาะการหมนของ node หลงจากการน า node เขาและการน า node ออก

7.2 Red-Black Tree Red-Black Tree เปน Tree ทคดคนข นโดย Rudolf Bayer ในป 1972 และมชอเรยกในครงนนวา Symmetric binary B-tree ซงเปน tree ทมความสมดลอกตวหนงทใชคณสมบตของ BST เปนตวก าหนดการน าขอมลเขา เชนเดยวกบ AVL Tree และจะท าการปรบความสมดลโดยอตโนมตเชนเดยวกน แตจะมขอก าหนดอน ๆ อกบางประการทท าให Red-Black Tree ไม

เหมอนกบ Tree ทมความสมดลอน ๆ 7.2.1 ขอก าหนดของ Red-Black Tree Binary Search Tree ทมความสมดลพรอมทจะเปน Red-Black Tree จะตองมคณสมบตดงน

1. Node สามารถเปนไดทงสแดง หรอสด า

2. Node ทอยบนสด (root) จะตองเปนสด าเทานน 3. Node ทอยนอกสด หรอทเรยกวา null node เปนไดแคสด าเทานน 4. ถา node เปนสแดง ลกของ node นจะตองเปนสด าทงค 5. จ านวนของ node ทเปนสด าทก ๆ เสนทางจาก root ไปยง node นอกสด (null node)

จะเทากน

ภาพท 7.26 Red-Black Tree (แสดง null nodes)

ในภาพท 7.26 node ทมสแดงจะเปนเสนประ node ทมสด าจะเปนเสนทบ สวน null node จะเปน node ทบทไมมขอมลอยภายใน ในการน า node เขาส Red-Black Tree นนเราจะตองอาศยการใช null node เปนตวชวยท าใหขอก าหนดของ Red-Black Tree เปนจรงอยเสมอ ส งทเราตองค านงถงในการน าขอมลเขากคอ เราจะตองรกษาไวซ งคณสมบตของ Red-Black Tree ดงทไดกลาวไวกอนหนาน สของ node จะตองถกตอง และตองมความสมดลเชนเดยวกนกบ

Inside child

Aunt or Uncle of X

Outside child (X)

Parent

Grandparent of X 23

18

12

8 14

4

19 52

null nodes

Page 21: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

197

AVL Tree ดงนนเราจะตองมการเปลยนสของ node และ(หรอ) หมน node เพอรกษาไวซ งขอก าหนดดงกลาว 7.2.2 การน าขอมลเขา ปจจยทเราตองค านงอยตลอดเวลาในการน าขอมลเขากคอ ต าแหนงของ node ทตองน าเขา เนองจากวาเราตองการทจะใหการน า node เขาเปนไปตามเงอนไขเราจะก าหนดให node ทน าเขามสแดงเสมอ และการน าเขาเราจะใชหลกการของ Binary Search Tree เปนขอก าหนด คอน า node เขาตามปกต ตรวจสอบและปรบ tree ใหเปนไปตามขอก าหนดของ Red-Black Tree ทหลง เพราะฉะนนการน าขอมลเขา จะตองค านงถงสถานการณตอไปน (ดภาพท 7.27 ประกอบ)

1. parent ของ node ทน าเขาเปนสด า 2. parent ของ node ทน าเขาเปนสแดง และ node ทน าเขาเปน node ทอยดานนอก

(outside) 3. parent ของ node ทน าเขาเปนสแดง และ node ทน าเขาเปน node ทอยดานใน

(inside) เราจะพดถงการน าขอมลเขาเพยงดานใดดานหนงเทานน เชนในภาพท 7.27 เปนการแสดงการน าเขาทางดานซายของ tree เทานน เพราะวาการน าเขาทางดานขวากเหมอนกน เพยงแคกลบกนเทานน (symmetric)

ภาพท 7.27 ความเปนไปไดของต าแหนงของ node หลงจากการน าเขา (ไมแสดง null nodes)

7.2.3 กรณท 1 Parent ของ node ทน าเขาเปนสด า เราไดก าหนดไวกอนหนานวา node ใหมทน าเขาจะเปนสแดงเสมอ เพราะฉะนนการน า node เขาจะไมท าใหเกดปญหาใด ๆ เชน ม node ทเปนสแดงตอเนองกน 2 node (ขอก าหนดท 4) หรอจ านวนของ node ทเปนสด าจาก root ไปยง null node มไมเทากน (ขอก าหนดท 5) เราจง

ไมตองปรบปรง tree เพราะการน าขอมลเขาถกตองแลว 7.2.4 กรณท 2 Parent ของ node ทน าเขาเปนสแดง และ node ทน าเขาอยดานนอก ในกรณนเราจะตองตรวจสอบวา node ทน าเขามานนท าใหเกดความสมดล หรอไม ถามความสมดลส งทเราตองท ากคอ เปลยนสของ parent และพ (หรอนอง) ของ parent ใหเปนสด า แตถาท าใหเกดความไมสมดลเราตองท าการเปลยนสพรอมทงการหมน node ดงภาพท 7.28 ถง 7.32

G

P

50

12

25

X X

G

P

50

12

25

G

P

50

70

75

X

P เปนสด า P เปนสแดง ต าแหนงของ node อยดานนอก

P เปนสแดง ต าแหนงของ node อยดานใน

Page 22: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

198

ภาพท 7.28 node X อยดานนอก และ parent ของ X เปนสแดงและการเปลยนสของ node ยงท าให tree เปน Red-

Black tree อย เรากไมตองท าการหมนใด ๆ (ไมแสดง null nodes)

ภาพท 7.29 node X ท าใหเกดความไมสมดล ภาพท 7.30 การเปลยนสของ node 18 และ node 25 ท า

ใหเกดความไมสมดล (ไมแสดง null nodes)

G

P

50

12

25

X

75

G

P

50

12

25

X

75

X

12

G

P

50

18

25 75

X

12

G

P

50

18

25 75

Page 23: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

199

ภาพท 7.31 เปลยนสเสรจเรากหมน node 25 ไปทางขวา ภาพท 7.32 Red-Black Tree ทสมบรณ

(ไมแสดง null nodes)

7.2.5 กรณท 3 Parent ของ node ทน าเขาเปนสแดง และ node ทน าเขาอยดานใน ถา node ทน าเขาอยดานในเราจะตองท าการหมน node ทเปน parent ของ node ทน าเขาไปทางซาย เปลยนสของ node เหมอนทเราท าในกรณท 2 หลงจากนนหมน node ไปทางขวา ดงทแสดงในภาพประกอบน

ภาพท 7.33 การหมนซายของ node 12 ภาพท 7.34 หลงจากการหมน node และเปลยนส

(ไมแสดง null nodes)

12

50

18

25

75

X

12

G

P

50

18

25 75

X

G

P

50

12

25 75

18

X

G

P

50

18

25 75

12

Page 24: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

200

ภาพท 7.35 การหมน node 25 ไปทางขวา ภาพท 7.36 Red-Black Tree ทสมบรณ

(ไมแสดง null nodes)

7.2.6 การออกแบบ code ส าหรบการน าขอมลเขา ในการออกแบบ code นนเราจะตองเพม node ใหกบ Red-Black Tree เพอเอาไวใชเกบขอมลของ parent และเปนตวเชอมตอของ node ตาง ๆ ภายใน tree เมอมการโยกยาย node ดงนนเราจงเปลยน code ของ node ใหเปน

1: /**

2: Node for Red-black tree

3: */

4:

5: class RBNode<T> {

6: protected final int RED = 0, BLACK = 1;

7: protected RBNode<T> parent;

8: protected RBNode<T> left;

9: protected RBNode<T> right;

10: protected int color;

11: protected T key;

12:

13: //constructor for a null node (always black)

14: //left and right children are also null nodes

15: //see RBTree's constructor

16: public RBNode(T key) {

17: this.key = key;

18: color = BLACK;

19: parent = null;

20: }

21:

22: //constructor for new red node which has a parent and

23: //left and right nodes as nullNode

24: public RBNode(T key, RBNode<T> node, RBNode<T> nullNode) {

25: this.key = key;

26: color = RED;

27: parent = node;

28: left = right = nullNode;

29: }

30: }

Class RBNode ของเรามแค constructor 2 ตวส าหรบการสราง node ใหมกระบวนการอน ๆ จะอยใน class RBTree

Constructor ตวแรกเราใชส าหรบการสราง null node ซงจะเปนไดแค node ทมสด าเทานน สวน constructor ตวทสองเราใชส าหรบการสราง node ใหมทตองการน าเขา ซงตามขอก าหนดแลวจะเปนสแดงเสมอ

50

12

18 75

25

X

G

P

50

18

25 75

12

Page 25: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

201

เราเรมสราง code ของการน าขอมลเขาทมลกษณะการน าเขาคลายกบ Binary Search Tree ซงมสวนประกอบดงน (อยใน class RBTree) //insert key into tree

public void insert(T key) {

RBNode<T> current = root;

RBNode<T> parent = null;

RBNode<T> newNode;

//locating a spot to insert as well as a parent

while(current != nullNode) {

//no duplicates allowed

if(key.equals(current.key))

return;

//remember parent

parent = current;

if(key.compareTo(current.key) < 0)

current = current.left;

else

current = current.right;

}

//creates a new red node

newNode = new RBNode<T>(key, parent, nullNode);

//tree exists, insert as binary search tree

if(parent == null)

root = newNode; //first time insertion

else {

if(key.compareTo(parent.key) < 0)

parent.left = newNode;

else

parent.right = newNode;

}

//restore red-black properties after insertion

restoreAfterInsertion(newNode);

}

เชนเดยวกบการน าขอมลเขาส Binary Search Tree เราตองหาต าแหนงทเหมาะสมใหเจอกอน ซงเราไดท าใน while/loop โดยเราจะท าการจ า node ทเปน parent ของ node ทเราจะน าเขาดวย หลงจากนนเรากสราง node ใหมดวยค าสง newNode = new RBNode<T>(key, parent, nullNode);

nullNode ทเราสงไปให constructor ของ RBNode สรางจากค าสง nullNode = new RBNode<T>(null); ทอยใน contructor ของ class RBTree เมอได node ใหมแลวเราตองท าการตรวจสอบวา tree ของเราเปน tree ทมขอมลอยหรอไม ถาไมมเรากเพยงแตก าหนดให root ชไปท node ใหมน แตถามเรากตองดวาควรจะเชอม node ใหมนเขาทางขวา หรอทางซายของ parent เมอเชอมแลวเรากเรยกใช method restoreAfterInsertion() เพอท าการปรบ tree ใหเปนไปตามขอก าหนดของการเปน Red-Black Tree ตอไปซงม code ดงน //restore tree after insertion

private void restoreAfterInsertion(RBNode<T> X) {

//perform maintenance only when parent of X is red

while(X != root && X.parent.color == RED) {

//node was inserted on the left of the tree

if(X.parent == X.parent.parent.left) {

//y is X's parent sibling (aunt or uncle?)

RBNode<T> y = X.parent.parent.right;

//aunt or uncle of X is RED and X is an

//outside grandchild, do color flip

if(y.color == RED) {

X.parent.color = BLACK;

y.color = BLACK;

X.parent.parent.color = RED;

X = X.parent.parent;

}

Page 26: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

202

//aunt or uncle is black we have two cases

//either X is an inside or an outside grandchild

//for the first case we rotate left on X, re-color

//and rotate right on X's grandparent

//for the later, we re-color and rotate right

//on X' grandparent

else {

//X is a right grandchild (inside)

if(X == X.parent.right) {

X = X.parent;

rotateLeft(X);

}

//X is a left grandchild (outside)

//change X's parent's color to black

//change X's grandparent's color to red

//and perform a right rotation on X's grand

X.parent.color = BLACK;

X.parent.parent.color = RED;

rotateRight(X.parent.parent);

}

}

//node was inserted on the right of the tree

//just a mirror-image of the code above

else {

RBNode<T> y = X.parent.parent.left;

//aunt or uncle is red

if(y.color == RED) {

X.parent.color = BLACK;

y.color = BLACK;

X.parent.parent.color = RED;

X = X.parent.parent;

}

//aunt or uncle is black

else {

if(X == X.parent.left) {

X = X.parent;

rotateRight(X);

}

X.parent.color = BLACK;

X.parent.parent.color = RED;

rotateLeft(X.parent.parent);

}

}

}

//if somehow during our re-coloring X turned to red,

//and X became root, we must change it to black

root.color = BLACK;

}

หลงจากทเราทดสอบดวยโปรแกรม TestRedBlackTree.java

1: /**

2: Testing module for Red-Black Tree

3: */

4:

5: class TestRedBlackTree<T> {

6: public static void main(String[] args) {

7: RBTree<Integer> t = new RBTree<Integer>();

8: int[] key = {4, 7, 12, 15, 3, 5, 14, 18, 16, 17};

9:

10: for(int data : key) {

11: t.insert(data);

12: t.printTree();

13: }

14: }

15: }

ผลลพธทเราไดคอ 4(B)

4(B) 7(R)

Page 27: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

203

7(B) 4(R) 12(R)

7(B) 4(B) 12(B) 15(R)

7(B) 4(B) 3(R) 12(B) 15(R)

7(B) 4(B) 3(R) 5(R) 12(B) 15(R)

7(B) 4(B) 3(R) 5(R) 14(B) 12(R) 15(R)

7(B) 4(B) 3(R) 5(R) 14(R) 12(B) 15(B) 18(R)

7(B) 4(B) 3(R) 5(R) 14(R) 12(B) 16(B) 15(R) 18(R)

14(B) 7(R) 4(B) 3(R) 5(R) 12(B) 16(R) 15(B) 18(B) 17(R)

เราก าหนดใหผลลพธในบางบรรทดเปนตวหนาเพอใหผอานสงเกตวามการปรบปรง tree ให เปนไปตามขอก าหนด โดยครงแรกนนเกดข นเมอเราน าเอา 12 เขาส tree ซงท าใหเราได node ทเปนสแดง 2 node ตดกนและ node ทน าเขาเปน node ทอยดานนอกเราจงตองท าการเปลยน

ส parent ของ node นใหเปนสด า และเปลยนสของ grandparent ของ node นใหเปนสแดง พรอมทงหมน node ทเปน grandparent ไปทางซายหนงครง (ซงเปนการท ากลบกนของภาพท 7.33 – 7.36) หลงจากนนการปรบปรงกเกดข นอกครงหนงหลงจากทเราน าเอา 14 เขาส tree ซงท าใหเราตองท าการหมน node ทเปน parent ของ node ทน าเขาไปทางขวาหนงครง หลงจากนนกเปลยนส

ของ node ทเปน parent ใหเปนสด า และเปลยนสของ grandparent ใหเปนสแดง แลวจงท า

การหมน node ไปทางซายหนงครง (ดภาพประกอบ)

ภาพท 7.37 การน า node 14 เขาส tree และการหมน node ไปทางขวา (ไมแสดง null nodes)

ภาพท 7.38 การหมน node ไปทางซายหลงจากการเปลยนส ภาพท 7.39 Red-Black Tree ทสมบรณ

(ไมแสดง null nodes)

7

14

4 12

15 5 3

7

15

4 12

14 5 3

7

15

4 14

12 5 3

7

15

4 12

14 5 3

Page 28: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

204

หลงจากนนเรากมการปรบปรง tree อกสามครงคอ หลงจากการน า node 16, node 18 และ node 17 เขาส tree ซงเราจะทงไวใหผอานไดลองตรวจสอบดวยการเขยนภาพขนมาเอง 7.2.7การลบ node การลบ node ออกจาก Red-Black Tree กท าคลาย ๆ กบการลบ node ออกจาก BST กลาวคอ หา node ทตองการลบใหเจอ เมอเจอแลวกตองหา node ทจะตองมาแทน ซง node ทจะน ามาแทนนนจะตองรกษาคณสมบตของ BST ไวใหได และกเปนเรองทไมยากอะไร เพราะเราไดท ามากอนแลวในเรองของ AVL Tree แตส งส าคญหลงจากการดง node ออกกคอการรกษาขอก าหนดของ Red-Black Tree ในการลบ node ออกจาก tree ทใชเงอนไขของ BST เปนตวก าหนดการน าขอมลเขานน เราไมไดลบ node ทตองการออกจรง แตเปนการหา node ทมขอมลทกฎก าหนดไวมาแทนท (node ทมคานอยทสดทางขวา หรอ node ทมคามากทสดทางซาย) แลวจงลบ node ทหาได ทงไปซง node ทวานจะเปน node ทอยดานนอกสดเสมอ (leaf node) ดงนนการลบในลกษณะนของ Red-Black tree จงท าใหเสนทางจาก root node ไปยง leaf node มจ านวนของ black node นอยกวาเสนทางอน ๆ อยหนง node ถา node (V ในภาพ) เปนสด า

ภาพท 7.40 double black ทก าหนดขนหลงจากการลบ

ดงนนเพอใหการลบ node ของเราคงไวซ งขอก าหนดของการเปน Red-black Tree เราจงก าหนดให node นเปน double black node (node X ในภาพ) และเราจะท าการปรบปรง tree ใหเปน Red-black Tree ตอไปตามเงอนไขใน 7.2.3, 7.2.4, และ/หรอ 7.2.5 (ผอานควรตรวจสอบดวาถา node ทถกลบออกเปนสแดงเรากไมตองท าอะไรเลย)

ภาพท 7.41 การก าหนดให node ทถกลบเปน double black

node ทตองถกลบออกหลงจากการแทนคาแลว

X

V

X

เสนประ = double black

6

3

4

8

W U

X

6

3

4

X

การลบ node 8 ออกท าใหเกดเหตการณทเราเรยกวา double black

เราจงตองท าการปรบปรง tree ให

เปนไปตามขอก าหนด

Page 29: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

205

ภาพท 7.42 การก าหนดให node ทถกลบเปน double black

สรปข นตอนการลบ node ออกจาก Red-black Tree

1. ลบ node ตามปกตดวยกฎของ Binary Search Tree 2. ก าหนดให node X (node ทถกเลอกในกระบวนการลบของ BST) เปน double black

node ถา node X เปนสด า แลวด าเนนการตามเงอนไขใน 7.2.3, 7.2.4 และ/หรอ 7.2.5 ตามความเหมาะสม

หมายเหต:

1. ผอานอยาลมวา node X (double black node) เปนเพยง node สมมตทเราสรางขนเพอการปรบปรง tree ใหเปนไปตามเงอนไข ไมใช node ทมอยจรงใน tree

2. ภาพทแสดงเปน snap shot ของ tree ซงมความหมายวาอาจม sub-tree อยภายใต node ใด node หนงกได หรออาจเปน node ดานนอกทม null node เปน leaf

เง อนไขของการปรบปรง tree เมอมการลบเกดข น 7.2.8 Sibling (พหรอนอง) ของ node X มสด าและมลกสแดงหนง node

ภาพท 7.43 สวนหนงของ tree หลงจากการลบ node

ถาการลบ node ออกจาก tree ท าให

เกดสถานการณแบบน คอ node w มสด าและมลกเปนสแดงหนง node เรา

จะตองท าการเปลยนสของ node 5 ใหเปนสด า เปลยนสของ node 4 ให เปนสแดง ท าการหมนซายท node 4 หลงจากนนกท าการเปลยนส และ

หมน node ไปทางขวา ดงทแสดงในรปถดไป

ลกของ node 4 มสแดง

Sibling ของ node X มส

ด า

7

4

5

W

X

7

15

4 14

12 5 3

12

15

4 14

5 3

ตองการลบ

node 7

Node 12 เปน node ทเราตองน าไปแทน

Node 12 เดมเปนสด า เราจงตองก าหนดให

เปน double black

U

X X

U

Page 30: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

206

ภาพท 7.44 node ถกเปลยนสและหมนไปทางซาย ภาพท 7.45 หลงจากหมนซาย กอนการหมนขวา

ภาพท 7.46 หลงจากการหมน node 7 ไปทางขวา

7.2.9 Sibling ของ node X มสด าและลกท งสองกมสด า ในกรณทเหตการณนเกดข น ส งทเราตองท ากเปนเพยงแคการเปลยนสของ node เทานน ดงภาพทแสดงน

ภาพท 7.47 การเปลยนส node

การเปลยนสของ node ดงทแสดงในภาพอาจท าใหเกดปญหาขนไดเหมอนกน คอ จ านวนของ node ด าในเสนทางนมนอยกวาเสนทางอนหนงตว ดงนนเราอาจตองกลบไปแกไข tree ของเราใหมขอก าหนดทถกตอง ดงทเราไดแสดงใหดในกรณกอนหนาน (7.2.8)

7

4

5

W

7

5

4

W

X X

5

4 7

16

15 W

16

15 W

X X

Page 31: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

207

7.2.10 Sibling ของ node X มสแดง

ภาพท 7.48 sibling ของ node X มสแดง ภาพท 7.49 tree หลงจากการเปลยนส node 5 และ node 14 พรอม ทงการหมน node 14 หลงจากนน

ภาพท 7.50 tree หลงจากการเปลยนสเนองจาก node 7 มลกเปนสด า (null nodes ทงค)

สงทเกดข นจากการท sibling ของ node X เปนสแดงนนมกระบวนการหลก ๆ อยสองขนตอนคอ การเปลยนสของ node กอนการหมน และการเปลยนสของ node หลงจากการหมน ผอานจะเหนวา หลงจากทเราหมน node เรยบรอยแลว node 14 เปนสแดง และ node 7 เปนสด า (ภาพท 7.48 – 7.50) แตเนองจากวา node 7 เปน leaf node ทม null node อยแลวสอง node ดงนนเราตองท าการเปลยน node 14 เปนสด า และ node 7 เปนสแดง เพอใหถกตองตามขอก าหนด หลาย ๆ ครงการลบ node ออกจาก tree มกจะเกยวของกบกรณตาง ๆ มากกวาหนงกรณ ดงนนการเขยน code เพอรองรบการลบ node จะตองระมดระวงขนตอนเหลานนใหด สวนไหนทนาจะมากอนกตองมากอน สวนไหนทอาจใชรวมกนหลงจากกระบวนการอนเสรจส นลง กตองอยตามมา ซงถาเราออกแบบกระบวนการเหลานดแลว code ของเรากจะไมยาวจนเกนไปนก Code ทงหมดของการลบ node มดงน

14

5

7

W

4

5

4 14

7

W

node W เปนสด าไมได

เพราะม null node ทเปนสด าอย

X

X

5

4 14

7

Page 32: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

208

//delete a node from tree

public void delete(T key) {

RBNode<T> X;

RBNode<T> successor; //replacement node

RBNode<T> deleteNode; //node to be deleted

//find node to delete

deleteNode = root;

while(deleteNode != nullNode) {

//found a target node

if(key.equals(deleteNode.key))

break;

//not yet found, keep searching

else {

if(key.compareTo(deleteNode.key) < 0)

deleteNode = deleteNode.left;

else

deleteNode = deleteNode.right;

}

}

//node to delete is not in a tree, abort

if(deleteNode == nullNode) return;

//successor has a nullNode as a child (deleteNode is leaf)

if(deleteNode.left == nullNode ||

deleteNode.right == nullNode)

successor = deleteNode;

//find a successor with a nullNode as a child

//locate minimum node on the right

else {

successor = deleteNode.right;

while(successor.left != nullNode)

successor = successor.left;

}

//X is successor's only child

if(successor.left != nullNode)

X = successor.left;

else

X = successor.right;

//removing successor from parent chain

X.parent = successor.parent;

if(successor.parent != null) {

if(successor == successor.parent.left)

successor.parent.left = X;

else

successor.parent.right = X;

}

else

root = X;

//replace the key (keep the color)

if(successor != deleteNode)

deleteNode.key = successor.key;

//restore red-black properties after deletion

if(successor.color == BLACK)

restoreAfterDelete(X);

}

//restore tree after deletion

private void restoreAfterDelete(RBNode<T> X) {

//maintenance needed when black node was deleted

while(X != root && X.color == BLACK) {

//handle left side

if(X == X.parent.left) {

//w is a sibling of X (a right child)

RBNode<T> w = X.parent.right;

//sibling is red

if(w.color == RED) {

w.color = BLACK;

X.parent.color = RED;

rotateLeft(X.parent);

w = X.parent.right;

Page 33: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

209

}

//both children of w are black, change parent to red

//and reset X to its parent

if(w.left.color == BLACK &&

w.right.color == BLACK) {

w.color = RED;

X = X.parent;

}

//they are not both black, re-color and

//do double rotations, iff right child of w

//is black, otherwise do a left rotation

else {

//right child of w is black

if(w.right.color == BLACK) {

w.left.color = BLACK;

w.color = RED;

rotateRight(w);

w = X.parent.right;

}

//right child of w is red

//change w's color to its parent

//change its parent's color to black

//change right child's color to black

//rotate left on its parent

w.color = X.parent.color;

X.parent.color = BLACK;

w.right.color = BLACK;

rotateLeft(X.parent);

X = root; //set this new tree

}

}

//handle right side

//a mirror-image of code above

else {

RBNode<T> w = X.parent.left;

if(w.color == RED) {

w.color = BLACK;

X.parent.color = RED;

rotateRight(X.parent);

w = X.parent.left;

}

//if left and right nodes are black, their

//parent must be red

if(w.right.color == BLACK &&

w.left.color == BLACK) {

w.color = RED;

X = X.parent;

}

//w has one red node, two cases to consider

//if node on the left is black, we change color

//and rotate left on w, then we recolor and

//rotate right one more time

//if node on the left is red, we change color

//and rotate right

else {

if(w.left.color == BLACK) {

w.right.color = BLACK;

w.color = RED;

rotateLeft(w);

w = X.parent.left;

}

//left node is red

w.color = X.parent.color;

X.parent.color = BLACK;

w.left.color = BLACK;

rotateRight(X.parent);

X = root;

}

}

}

//if X became root, make sure it's black

X.color = BLACK;

}

Page 34: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

210

เพอใหเหนภาพชดขนเราจะน าขอมล [13, 22, 8, 18, 24, 25] เขาส tree และจะท าการลบ node 8 ออก

ภาพท 7.51 การลบ node 8 ท าใหกฎขอท 5 ถกละเมด

ภาพท 7.52 [ซายสด: การเปลยนสของ node 13 และ node 22] [กลาง: การหมน node 13 ไปทางซาย] [ขวาสด: การเปลยนสของ node 13 และ node 18]

การหมน node ไปทางซาย และทางขวานนกท าคลาย ๆ กบทเราท าใน AVL Tree แตจะตางกนตรงทเราตองดแล node ทเปน parent ดวย ซง code ของกระบวนการทงสองมดงน private void rotateLeft(RBNode<T> X) {

RBNode<T> y = X.right;

X.right = y.left;

if(y.left != nullNode)

y.left.parent = X;

if(y != nullNode)

y.parent = X.parent;

if(X.parent != null) {

if(X == X.parent.left)

X.parent.left = y;

else

X.parent.right = y;

}

13

8

18

22

24

25

13

18

22

24

25

13

18

22

24

25

13

18

22

24

25

13

18

22

24

25

Page 35: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

211

else

root = y;

y.left = X;

if(X != nullNode)

X.parent = y;

}

private void rotateRight(RBNode<T> X) {

RBNode<T> y = X.left;

X.left = y.right;

if(y.right != nullNode)

y.right.parent = X;

if(y != nullNode)

y.parent = X.parent;

if(X.parent != null) {

if(X == X.parent.right)

X.parent.right = y;

else

X.parent.left = y;

}

else

root = y;

y.right = X;

if(X != nullNode)

X.parent = y;

}

เราไดรวบรวม code ทงหมดของ Red-Black Tree มาไวใหอกครงหนง

1: /**

2: Red-black tree

3: */

4:

5: class RBTree<T extends Comparable<? super T>> {

6: private RBNode<T> root;

7: private RBNode<T> nullNode;

8: private final int RED = 0, BLACK = 1;

9:

10: //use nullNode to denote all leaf nodes

11: public RBTree() {

12: //create a null node with black color

13: nullNode = new RBNode<T>(null);

14: nullNode.left = nullNode.right = nullNode;

15: //start with an empty tree

16: root = nullNode;

17: }

18:

19: //insert key into tree

20: public void insert(T key) {

21: RBNode<T> current = root;

22: RBNode<T> parent = null;

23: RBNode<T> newNode;

24:

25: //locating a spot to insert as well as a parent

26: while(current != nullNode) {

27: //no duplicates allowed

28: if(key.equals(current.key))

29: return;

30: //remember parent

31: parent = current;

32: if(key.compareTo(current.key) < 0)

33: current = current.left;

34: else

35: current = current.right;

36: }

37:

38: //creates a new red node

39: newNode = new RBNode<T>(key, parent, nullNode);

Page 36: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

212

40: //tree exists, insert as binary search tree

41: if(parent == null)

42: root = newNode; //first time insertion

43: else {

44: if(key.compareTo(parent.key) < 0)

45: parent.left = newNode;

46: else

47: parent.right = newNode;

48: }

49:

50: //restore red-black properties after insertion

51: restoreAfterInsertion(newNode);

52: }

53:

54: //restore tree after insertion

55: private void restoreAfterInsertion(RBNode<T> X) {

56: //perform maintenance only when parent of X is red

57: while(X != root && X.parent.color == RED) {

58: //node was inserted on the left of the tree

59: if(X.parent == X.parent.parent.left) {

60: //y is X's parent sibling (aunt or uncle?)

61: RBNode<T> y = X.parent.parent.right;

62: //aunt or uncle of X is RED and X is an

63: //outside grandchild, do color flip

64: if(y.color == RED) {

65: X.parent.color = BLACK;

66: y.color = BLACK;

67: X.parent.parent.color = RED;

68: X = X.parent.parent; //point X to grand

69: }

70: //aunt or uncle is black we have two cases

71: //either X is an inside grandchild or an outside grandchild

72: //for the first case we rotate left on X, re-color, and

73: //rotate right on X's grandparent for the later,

74: //we re-color and rotate right on X' grandparent

75: else {

76: //X is a right grandchild (inside)

77: if(X == X.parent.right) {

78: X = X.parent;

79: rotateLeft(X);

80: }

81: //X is a left grandchild (outside)

82: //change X's parent's color to black

83: //change X's grandparent's color to red

84: //and perform a right rotation on X's grand

85: X.parent.color = BLACK;

86: X.parent.parent.color = RED;

87: rotateRight(X.parent.parent);

88: }

89: }

90: //node was inserted on the right of the tree

91: //just a mirror-image of the code above

92: else {

93: RBNode<T> y = X.parent.parent.left;

94: //aunt or uncle is red

95: if(y.color == RED) {

96: X.parent.color = BLACK;

97: y.color = BLACK;

98: X.parent.parent.color = RED;

99: X = X.parent.parent;

100: }

101: //aunt or uncle is black

102: else {

103: if(X == X.parent.left) {

104: X = X.parent;

105: rotateRight(X);

106: }

107: X.parent.color = BLACK;

108: X.parent.parent.color = RED;

109: rotateLeft(X.parent.parent);

110: }

111: }

112: }

113: //if somehow during our re-coloring X's color is changed to red,

Page 37: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

213

114: //and X became root, we must change it back to black

115: root.color = BLACK;

116: }

117:

118: //delete a node from tree

119: public void delete(T key) {

120: RBNode<T> X;

121: RBNode<T> successor; //replacement node

122: RBNode<T> deleteNode; //node to be deleted

123: //find node to delete

124: deleteNode = root;

125: while(deleteNode != nullNode) {

126: //found a target node

127: if(key.equals(deleteNode.key))

128: break;

129: //not yet found, keep searching

130: else {

131: if(key.compareTo(deleteNode.key) < 0)

132: deleteNode = deleteNode.left;

133: else

134: deleteNode = deleteNode.right;

135: }

136: }

137: //node to delete is not in a tree, abort

138: if(deleteNode == nullNode) return;

139:

140: //successor has a nullNode as a child (deleteNode is leaf)

141: if(deleteNode.left == nullNode || deleteNode.right == nullNode)

142: successor = deleteNode;

143: //find a successor with a nullNode as a child

144: //locate minimum node on the right

145: else {

146: successor = deleteNode.right;

147: while(successor.left != nullNode)

148: successor = successor.left;

149: }

150:

151: //X is successor's only child

152: if(successor.left != nullNode)

153: X = successor.left;

154: else

155: X = successor.right;

156:

157: //removing successor from parent chain

158: X.parent = successor.parent;

159: if(successor.parent != null) {

160: if(successor == successor.parent.left)

161: successor.parent.left = X;

162: else

163: successor.parent.right = X;

164: }

165: else

166: root = X;

167:

168: //replace the key (keep the color)

169: if(successor != deleteNode)

170: deleteNode.key = successor.key;

171:

172: //restore red-black properties after deletion

173: if(successor.color == BLACK)

174: restoreAfterDelete(X);

175: }

176:

177: //restore tree after deletion

178: private void restoreAfterDelete(RBNode<T> X) {

179: //maintenance needed when black node was deleted

180: while(X != root && X.color == BLACK) {

181: //handle left side

182: if(X == X.parent.left) {

183: //w is a sibling of X (a right child)

184: RBNode<T> w = X.parent.right;

185: //sibling is red

186: if(w.color == RED) {

187: w.color = BLACK;

Page 38: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

214

188: X.parent.color = RED;

189: rotateLeft(X.parent);

190: w = X.parent.right;

191: }

192: //both children of w are black, change their parent to red

193: //and reset X to its parent

194: if(w.left.color == BLACK && w.right.color == BLACK) {

195: w.color = RED;

196: X = X.parent;

197: }

198: //they are not both black, re-color and

199: //do double rotations, iff right child of w

200: //is black, otherwise do a left rotation

201: else {

202: //right child of w is black

203: if(w.right.color == BLACK) {

204: w.left.color = BLACK;

205: w.color = RED;

206: rotateRight(w);

207: w = X.parent.right;

208: }

209: //right child of w is red, change w's color to black

210: //change its parent's color to black

211: //change right child's color to black

212: //rotate left on its parent

213: w.color = X.parent.color;

214: X.parent.color = BLACK;

215: w.right.color = BLACK;

216: rotateLeft(X.parent);

217: X = root; //set this new tree

218: }

219: }

220: //handle right side

221: //a mirror-image of code above

222: else {

223: RBNode<T> w = X.parent.left;

224: if(w.color == RED) {

225: w.color = BLACK;

226: X.parent.color = RED;

227: rotateRight(X.parent);

228: w = X.parent.left;

229: }

230: //if left and right nodes are black, their

231: //parent must be red

232: if(w.right.color == BLACK && w.left.color == BLACK) {

233: w.color = RED;

234: X = X.parent;

235: }

236: //w has one red node, two cases to consider

237: //if node on the left is black, we change color

238: //and rotate left on w, then we recolor and

239: //rotate right one more time

240: //if node on the left is red, we change color

241: //and rotate right

242: else {

243: if(w.left.color == BLACK) {

244: w.right.color = BLACK;

245: w.color = RED;

246: rotateLeft(w);

247: w = X.parent.left;

248: }

249: //left node is red

250: w.color = X.parent.color;

251: X.parent.color = BLACK;

252: w.left.color = BLACK;

253: rotateRight(X.parent);

254: X = root;

255: }

256: }

257: }

258: //if X became root, make sure it's black

259: X.color = BLACK;

260: }

261:

Page 39: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

215

262: //rotates left on node X

263: private void rotateLeft(RBNode<T> X) {

264: RBNode<T> y = X.right;

265: X.right = y.left;

266: if(y.left != nullNode)

267: y.left.parent = X;

268:

269: if(y != nullNode)

270: y.parent = X.parent;

271:

272: if(X.parent != null) {

273: if(X == X.parent.left)

274: X.parent.left = y;

275: else

276: X.parent.right = y;

277: }

278: else

279: root = y;

280:

281: y.left = X;

282: if(X != nullNode)

283: X.parent = y;

284: }

285:

286: //rotates right on node X

287: private void rotateRight(RBNode<T> X) {

288: RBNode<T> y = X.left;

289:

290: X.left = y.right;

291: if(y.right != nullNode)

292: y.right.parent = X;

293:

294: if(y != nullNode)

295: y.parent = X.parent;

296:

297: if(X.parent != null) {

298: if(X == X.parent.right)

299: X.parent.right = y;

300: else

301: X.parent.left = y;

302: }

303: else

304: root = y;

305:

306: y.right = X;

307: if(X != nullNode)

308: X.parent = y;

309: }

310:

311: public void printTree() {

312: printTree(root);

313: System.out.println();

314: }

315:

316: private void printTree(RBNode<T> t) {

317: if(t != nullNode) {

318: System.out.print(t.key + "(" + alpha(t.color) + ")" + " ");

319: printTree(t.left);

320: printTree(t.right);

321: }

322: }

323:

324: private char alpha(int value) {

325: return value == RED ? 'R' : 'B';

326: }

327: }

Page 40: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

216

7.3 Splay Tree Splay Tree เปน BST อกตวหนงทปรบความสมดลดวยตวเองหลงจากการกระท าตาง ๆ กบ tree เชน การน าขอมลเขาหรอลบ node ออกจาก tree การสราง code ขนมาใชงานของ splay tree นนท าไดงายกวา AVL tree หรอ Red-Black treeผทคดคน Splay tree คอ Daniel Sleator และ Robert Tarjan 7.3.1 โครงสรางของ Splay Tree โครงสรางของ Splay tree นนจะแตกตางกบ search tree ตวอนตรงทมการน าเอากระบวนการทเรยกวา splaying มาใชทกครงทมการเขาหา node ทอยใน tree การ splay หมายถงการทเราน า node ทมการเขาหา2กลบขนไปยงต าแหนง root (move-to-root operation) คณสมบตนท าใหขอมลทเพงถกเขาหาหมาด ๆ งายตอการเขาหาอกครง ภาพท 7.53 แสดง splay tree หลงจากการน าขอมลเขา

ภาพท 7.53 Splay tree หลงจากน าขอมล 18, 8, 23, และ 12 เขา

ภาพท 7.53 แสดง tree ทเกดจากการน าขอมล 18, 8, 23, และ 12 เขา (ตามล าดบ) จะเหนวาขอมลทถกน าเขาครงหลงสดจะอยในต าแหนง root เสมอและ tree กยงคงคณสมบตของ BST ไวทกประการ การลบหรอการเขาหา node ทอยใน tree นนกเหมอนกน (กบการน าเขา) เราตองน า node ทมการเขาหากลบขนไปยง root และกระบวนการดงกลาวเราเรยกวาการ splay ในการ splay นนเราตองค านงถงกรณตาง ๆ อยสามกรณคอ zig-zag, zig-zig, และ zig 7.3.2 การ Splay เมอ node X ไดรบการเขาหาเราตองท าการ splay เพอให X ไปอยในต าแหนง root ซงเปนกระบวนการทท าเปนขนตอน (ตามล าดบ) จนกระทง X อยดานบนสดของ tree เพราะฉะนนการเลอน X ขนดานบนจงขนอยกบต าแหนงของ X, ต าแหนงของ parent ของ X และต าแหนงของ grand parent ของ X (ถาม) 7.3.2.1 Zig-zag หมายถงการท X เปนลกทอยทางดานขวาของ P และ P เปนลกทอยทางดานซายของ G ดงทแสดงในรป 7.54 เราจะเปลยนให P เปนลกทอยทางดานซายของ X และเปลยนให G เปนลกทอยทางดานขวาของ X สวน sub-tree ของแตละ node กยงคงรกษาคณสมบตของ BST ไว เชนเดม

2 ในทนการเขาหาหมายถง การน าขอมลเขา การลบขอมล หรอการดขอมล (look up)

18 8

18

23

18

8

12

8 23

18

Page 41: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

217

ภาพท 7.54 การ splay ในกรณท X เปนลกทางดานขวาของ P และ P เปนลกทางดานซายของ G

7.3.2.2 Zig-zig หมายถงการท X เปนลกทอยทางซายของ P และ P เปนลกทอยทางซายของ G เราตองเปลยน P ใหเปนลกทางขวาของ X และ G ใหเปนลกทางขวาของ P

ภาพท 7.55 การ splay ในกรณท X เปนลกทางซายของ P และ P เปนลกทางซายของ G

เราจะท าการ splay ดวยวธ zig-zig หรอ zig-zag เมอ X ม grand parent เทานน ส าหรบกรณท X ไมม grand parent แตมเพยงแค parent เราจะท าการ splay ดวยวธทเรยกวา zig ซงมขนตอนการท างานดงน

25

19

13

A B

C

D

P

X

G

13

19

25

A

B

C D

G

P

X

1

2

1. หมน node 25 ไปทางขวา (zig)

2. หมน node 19 ไปทางขวา (zig)

25

13

19

A

B C

D

G

P

X

19

13 25

A B C D

G

X

P

1

2

1. หมน node 13 ไปทางซาย (zig) 2. หมน node 25 ไปทางขวา (zag)

Page 42: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

218

7.3.2.3 Zig ในกรณท X มแค parent เรากเพยงแคหมน node P เพอให node X มาอยในต าแหนง root

ภาพท 7.56 การ splay เมอ X ไมม grand parent แตมแค parent

ทงสามกรณทกลาวมานนเปนเพยงแคกรณตวอยางทางดานซายเทานน แตโดยความเปนจรงแลว เรายงมกรณทางดานขวาทตองค านงถง ซงโดยทางปฏบตกเปนการกระท าทเหมอนกนแตท าในทางตรงกนขาม (symmetric operation) เราจะทงไวใหผอานวเคราะหถงกรณดงกลาวเอง

ผใหก าเนด Splay tree ไดเสนอใหการ splay นนเปนการ splay จากบนลงลาง (top –down splay tree) ทงนกเนองจากวาการสราง tree แบบนงายกวาการสรางทใชวธการแบบลางขนบน เชนทไดแสดงใหดใน 7.3.2.1 ถง 7.3.2.3 (bottom-up splay tree) 7.3.3 การ splay จากบนลงลาง (Top-down) การสราง tree ดวยการ splay จากบนลงลางนนมวธการคราว ๆ คอ ในขณะทเราก าลงลงส tree

เพอเขาหา node X เราตองท าการยาย node ทอยระหวางทางของการคนหาออกจาก tree (ทงตว node และ sub-tree ของ node ดวย) พรอมกนนเราตองท าการหมน node (zig, zig-zig, หรอ zig-zag) เพอรกษาคณสมบตของ splay tree ไว ในการ implement นนเราจะใช tree ทงหมดสามตว คอ L, R, และ tree ทอยในเงอนไข (middle tree) เมอเรามาถง node X เรารวา X เปน root ของ sub-tree นนเราจะใช L เปนตวเกบ node ทมคานอยกวา X และจะใช R เกบ node ทมคามากกวา X

เมอเรมตนนน X เปน root ของ tree และ L กบ R เปน tree ทไมม node อยเลย (empty) เมอเราลงไปใน tree ครงละสองระดบเราจะเจอกบ node คหนงทเราตองท าการยาย ซงกข นอยกบวา node ทงสองนอยกวาหรอมากกวา X เราจะยาย node และ sub-tree ของมนเขาส L หรอ R รวมไปถง sub-tree ทไมไดอยใน path ทใชเขาหา X เพราะฉะนน node ปจจบนท algorithm ก าลงตรวจสอบอยจงเปน root ของ tree ทอยตรงกลางเสมอ และเมอเราเขาถง X แลวเรากท าการเชอม node ทอยใน L และ R เขากบ tree ทอยตรงกลาง (ท าให X เปน root ของ tree) ขนตอนทเหลอจงเปนการน า node เขาส L และ R พรอมกบการเชอมของ L และ R เขาส tree

เราจะแสดงกระบวนการดงกลาวดวยภาพตอไปน

19

13

A

B C

X

P

19

13

A B

C

P

X

Page 43: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

219

ภาพท 7.57 Top-down splay ดวยการ zig

ระหวางการ splay นนถาการหมนของเราอยในขายของ zig เราจะก าหนดให tree ทม Y เปน root นนเปน root ใหมของ tree ทอยตรงกลาง พรอมกนนเราจะก าหนดให X และ sub-tree ของ X เปนลกทอยทางซายของคาทนอยทสดของ R กระบวนการนท าให X เปนคาทนอยทสด (จากภาพท 7.57 เราท าใหลกทางซายของ X เปน null) ส าหรบกรณทการหมนอยในขายของ zig-zig นนเราตองท าการหมน node X และ Y เพมข นมาจากกระบวนการทเราท าในการ zig (ดภาพท 7.58 ประกอบ)

ภาพท 7.58 กระบวนการ zig-zig และการหมน node X และ Y

และในกรณของการ zig-zag นนเราจะก าหนดให Y เปน root ของ tree ทอยตรงกลาง (โดยปกตเราจะให Z เปนแตเนองจากวาเราไมตองท าการหมน node – เราเรยกวธหมนแบบนวา simplified zig-zag ผอานอาจสงสยวาท าไม สาเหตกเพราะวาเราตองการใหการเขยน code นนงายขน เพราะวาการ zig-zag กลายมาเปน zig) และเราจะเชอม X และ Z ดงทแสดงในภาพท 7.59

L R

X

A B

Y

L R

X

A

B

Y

zig

L

X

A

B

Z

Y

C

R R

X

A

B

Z

Y

C

L

zig-zig

Page 44: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

220

ภาพท 7.59 กระบวนการ zig-zag แบบ simplified

ขนตอนทเหลออยกคอการน าเอาทง L, R, และ tree ทอยตรงกลางมาประกอบกนใหเปน tree ตวเดยวดงภาพท 7.60

ภาพท 7.60 ขนตอนสดทายของการ splay จากบนลงลาง

เชนเดยวกบทเราไดพดถง AVL tree และ Red-Black tree เราไมไดแสดงกระบวนการ splay ในทศตรงกนขาม (symmetric operation) ผอานควรศกษาและวาดภาพดงกลาวเอง เพอใหเหนภาพชดเจนยงข นเราจะแสดงกระบวนการทงหมดอกครงหนงดวยขอมลทมอยใน tree ทเหนนโดยเราจะท าการคนหา node 24

L R

X

A

B

Z

Y

C X

C

A

B

Z

Y

R L

zig-zag

X

A B

L R

X

R L

B A

Page 45: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

221

ภาพท 7.61 Splay tree ตวอยาง เพอการคนหา node 24

หลงจากทเราตรวจสอบและเดนเขาหา tree ครงละสองระดบเรากมาถง node 26 (เปนขนตอนของการ zig-zag: 18 31 26) เรากก าหนดให node 31 เปน root ของ tree ทอยตรงกลาง (ถาเปน zig-zag ตามปกต node 26 จะเปน root แตเราจะใชวธของ simplified zig-zagแทน) พรอมกบท าการเชอม node 18 และ sub-tree ของ node 18 เขากบ tree L เรากจะได tree ดงทแสดงในภาพท 7.62

ภาพท 7.62 simplified zig-zag

เมอเราเดนเขาหา tree ตอไปเรากจะเจอกรณของการ zig-zig (31 26 21) เรากน าเอา node 21 ขนมาเปน root ของ tree ตรงกลางพรอมกบท าการเชอม node เหลานเขากบ tree R หลงจากการหมนระหวาง node 26 และ node 31 ดงทแสดงในภาพท 7.63

18

L R

13

5 15

31

26 36

21 30

24 19

Empty Empty

R

18

13

5 15

31

26 36

21 30

24 19

Left Middle

Empty

Page 46: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

222

ภาพท 7.63 การ zig-zig และการหมน node

ภาพท 7.64 การ zig และการเชอม node 19 และ 21 เขาส tree ทางซาย

เมอเราท าการ zig จาก node 21 กบ node 24 เรากได node 24 เปน root สวน node 19 และ

node 21 กไปเชอมอยกบ node 18 ดงทแสดงในภาพท 7.63 ขนตอนสดทายทเราตองท ากคอการรวมเอา tree ทงสามเขาดวยกน ซงกท าใหเราได tree ทม 24 เปน root node ดงทแสดงในภาพท 7.64

ภาพท 7.65 Tree หลงจากการคนหา node 24

การคนหาทไมเจอ node ทตองการกท าให node ทก าลงถกตรวจสอบ ณ เวลานนยายขนไปเปน root node เชนเดยวกน เชนสมมตวาเราตองการคนหา node 22 ของ tree ในภาพท 7.65 เราก

18

13

5 15

21

24 19 31

26

36 30

Left Middle Right

24

31

26

36 30

18

13

5 15 21

19

Left Middle Right

18

13

5 15 21

19

24

31

26

36 30

Page 47: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

223

จะได tree ทม node 21 เปน root node แต sub-tree ทอยทางดานขวากจะไมเหมอนเดม (node 24 จะมาเชอกบ node 26) Code ของการ splay แบบบนลงลางมดงน private SplayNode<T> splay(T key, SplayNode<T> t) {

SplayNode<T> L; //left tree

SplayNode<T> R; //right tree

header.left = header.right = nullNode;

L = R = header;

nullNode.key = key;

while(true) {

//descend two levels on the left

if(key.compareTo(t.key) < 0) {

if(key.compareTo(t.left.key) < 0) {

t = rotateRight(t);

}

if(t.left == nullNode)

break;

//move nodes to the right tree

R.left = t;

R = t;

t = t.left;

}

//descend two levels on the right

else if(key.compareTo(t.key) > 0) {

if(key.compareTo(t.right.key) > 0) {

t = rotateLeft(t);

}

if(t.right == nullNode)

break;

//move nodes to the left tree

L.right = t;

L = t;

t = t.right;

}

else break;

}

//reattach left and right trees

L.right = t.left;

R.left = t.right;

t.left = header.right;

t.right = header.left;

return t;

}

7.3.4 การน าขอมลเขา การน าขอมลเขาส Splay tree นนเมอเราสราง node ใหมแลวเรากตองตรวจสอบดวา tree ของเรามขอมลอยหรอไม ถาไมมเรากสราง tree ทมเพยงแค node ใหมนแตถามเราตองท าการ splay ดวยขอมลทเราตองการน าเขา ซงจะท าให tree ของเราม root ตวใหม (เราตองไมลมวาการ splay จะท าให tree เปลยนรป) ถาขอมลใน root ใหมมคานอยกวาขอมลใน node ใหมเรากจะน าเอา root ใหมนพรอมกบ sub-tree ทอยทางดานซายมาเชอตอกบลกทางซายของ node

ใหม แตถาขอมลของ root ใหมมคามากกวาเรากจะน าเอา root ใหมและ sub-tree ทางขวามาเชอมกบลกทางขวาของ node ใหม 7.3.5 การดงขอมลออก การลบ node ออกจาก tree เรมดวยการคนหา node ทมขอมลตามทตองการดวยการ splay ซงเรารวาถาหาเจอ node นจะเปน root ซงเราตองแทนคาของ node นดวยการคนหา node ทม

ขอมลนอยทสดทางดานขวา (หรอผอานอาจเปลยนใหเปน node ทมขอมลมากทสดทางซายกได) ซงกท าไดดวยการ splay เชนเคยและการ splay นจะการนตวา node นเปน node ทมขอมลนอยทสด (จรง ๆ แลวกคอ node ทมคา (มาก) ตอจาก node ทตองการลบออกนนเอง)

Page 48: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

224

7.3.6 การคนหาขอมล การคนหาขอมลนนเรากเพยงแตเรยกใชกระบวนการ splay ดวยขอมลทตองการคนหา ซงกจะท าใหขอมลนมาอยในต าแหนง root ถามอยจรงใน tree เรากเพยงแตตรวจสอบขอมลตวนเทานนเอง เราไมไดแสดง code ของการน าขอมลเขา การดงขอมลออก หรอการคนหาทงนเพราะวาเราได น าเอา code ทงหมดมาแสดงไว (ทเดยว) ดงทเหนน

1: /**

2: Top-down Splay Tree

3: */

4:

5: public class SplayTree<T extends Comparable<? super T>> {

6: private SplayNode<T> root;

7: private SplayNode<T> nullNode;

8: private SplayNode<T> newNode = null;

9: private SplayNode<T> header = new SplayNode<T>(null);

10:

11: //use nullNode to denote all leaf nodes

12: public SplayTree() {

13: nullNode = new SplayNode<T>(null);

14: nullNode.left = nullNode.right = nullNode;

15: //start with an empty tree

16: root = nullNode;

17: }

18:

19: //insert key into tree

20: public void insert(T key) {

21: //create new node with given key

22: if(newNode == null)

23: newNode = new SplayNode<T>(null);

24: newNode.key = key;

25:

26: //first time insertion, make one node tree

27: if(root == nullNode) {

28: newNode.left = newNode.right = nullNode;

29: root = newNode;

30: }

31: //tree exists

32: else {

33: //move candidate node to root

34: root = splay(key, root);

35:

36: //insert new node to this tree

37: if(key.compareTo(root.key) < 0) {

38: newNode.left = root.left;

39: newNode.right = root;

40: root.left = nullNode;

41: root = newNode;

42: }

43: else if(key.compareTo(root.key) > 0) {

44: newNode.right = root.right;

45: newNode.left = root;

46: root.right = nullNode;

47: root = newNode;

48: }

49: else return; //duplicate key - do nothing

50: }

51: newNode = null;

52: }

53:

54: //delete node with a given key

55: public void delete(T key) {

56: SplayNode<T> t;

57:

58: //locate node with a given key,

59: //if found, it's at root

60: root = splay(key, root);

61:

62: //do nothing if key doesn't exist

Page 49: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

225

63: if(root.key.compareTo(key) != 0)

64: return;

65:

66: //delete root node

67: if(root.left == nullNode)

68: t = root.right;

69: //locate smallest key on the right,

70: //splay it to root and connect left child

71: else {

72: t = root.right;

73: t = splay(key, t);

74: t.left = root.left;

75: }

76: root = t;

77: }

78:

79: //search for a node with a given key

80: public boolean search(T key) {

81: //node doesn't exist

82: if(root == nullNode)

83: return false;

84:

85: //if found, it's at root

86: root = splay(key, root);

87:

88: return root.key.compareTo(key) == 0;

89: }

90:

91: //top-down splaying

92: private SplayNode<T> splay(T key, SplayNode<T> t) {

93: SplayNode<T> L; //left tree

94: SplayNode<T> R; //right tree

95:

96: header.left = header.right = nullNode;

97: L = R = header;

98: nullNode.key = key;

99:

100: while(true) {

101: //descend two levels on the left

102: if(key.compareTo(t.key) < 0) {

103: if(key.compareTo(t.left.key) < 0) {

104: t = rotateRight(t);

105: }

106: if(t.left == nullNode)

107: break;

108: //move nodes to the right tree

109: R.left = t;

110: R = t;

111: t = t.left;

112: }

113: //descend two levels on the right

114: else if(key.compareTo(t.key) > 0) {

115: if(key.compareTo(t.right.key) > 0) {

116: t = rotateLeft(t);

117: }

118: if(t.right == nullNode)

119: break;

120: //move nodes to the left tree

121: L.right = t;

122: L = t;

123: t = t.right;

124: }

125: else break;

126: }

127: //reattach left and right trees

128: L.right = t.left;

129: R.left = t.right;

130: t.left = header.right;

131: t.right = header.left;

132:

133: return t;

134: }

135:

136: //rotate right once (same as AVL)

Page 50: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

226

137: private SplayNode<T> rotateRight(SplayNode<T> X) {

138: SplayNode<T> temp = X.left;

139: X.left = temp.right;

140: temp.right = X;

141:

142: return temp;

143: }

144:

145: //rotate left once (same as AVL)

146: private SplayNode<T> rotateLeft(SplayNode<T> X) {

147: SplayNode<T> temp = X.right;

148: X.right = temp.left;

149: temp.left = X;

150:

151: return temp;

152: }

153:

154: //pre-order traversal

155: private void pretraversal(SplayNode<T> node, StringBuffer buf) {

156: if(node != nullNode) {

157: buf.append(node.key + ", ");

158: pretraversal(node.left, buf);

159: pretraversal(node.right, buf);

160: }

161: }

162:

163: public String toString() {

164: StringBuffer buf = new StringBuffer();

165: buf.append("(");

166: pretraversal(root, buf);

167: buf.delete(buf.length()-2, buf.length());

168: buf.append(")");

169:

170: return new String(buf);

171: }

172: }

สวน code ของ SplayNode กมดงน

1: /**

2: Splay node for (Top-down) Splay Tree

3: */

4:

5: public class SplayNode<T> {

6: T key; //key to insert

7: SplayNode<T> left; //left child

8: SplayNode<T> right; //right child

9:

10: //default constructor

11: public SplayNode(T key) {

12: this.key = key;

13: this.left = this.right = null;

14: }

15: }

ผอานควรทดสอบการท างานของ splay tree ดวยการใชกลมขอมลทตางกนเพอใหเกดความเขาใจการท างานของการน าขอมลเขา การลบขอมล และการคนหาขอมลไดดย งข น สรป ในบทนเราไดพดถงโครงสรางของ AVL Tree, Red-Black tree, และ Splay Tree ซงทงสามตวเปน tree ทเมอมการเขาหา node ใด ๆ กจะปรบความสมดลโดยอตโนมต เราไดพดถง การน าขอมลเขา การดงขอมลออก และการคนหาขอมล การปรบความสมดลของ AVL Tree เราใชคาความแตกตางของความสงของ tree ทางซายและทางขวาเปนตวก าหนด ถาสงเกนกวาหนงเราจงจะปรบ tree การปรบความสมดลของ Red-Black Tree เราใชสของ node และกฎขอทหาเปนตวก าหนด นนกคอเราไมสามารถม node สองตวตดกนเปนสแดง และจ านวนของ black node จาก root ไปยง leaf node ใด ๆ ตองมเทากน การปรบความสมดลของ Splay Tree เราใช

ขอมลทน าเขาครงลาสด หรอ node ทมการเขาหาเปนตวก าหนดซงท าใหขอมลเหลานอยไมหางจาก root node เทาใดนก โดยรวมแลวเราไดพดถง

Page 51: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

บทท 7 Self-Balanced Binary Search Trees

227

ขอก าหนดของ AVL Tree, Red-Black Tree, และ Splay Tree การน าขอมลเขา และการดงขอมลออก การคนหาขอมล การปรบความสมดลของ AVL Tree, Red-Black Tree, และ Splay Tree

แบบฝกหด 1. จาก AVL Tree ทก าหนดให จงเขยนภาพของ Tree ทเกดข นหลงจากการลบ node

ดงตอไปน (ใหใช AVL Tree ทก าหนดใหทกครงกอนการลบ node)

ก. ลบ node k ง. ลบ node a ช. ลบ node h ข. ลบ node c จ. ลบ node g ค. ลบ node j ฉ. ลบ node m

2. จงเขยน method ทนบจ านวนของ node ในแตระดบทมอยใน BST เชน จากรปในขอ 1

ระดบ 0 มหนง node ระดบหนงม 2 node ระดบสองม 4 node ระดบสามม 5 node และระดบสม 1 node ใหเขยนโปรแกรมทดสอบ

3. จงแสดงภาพของ AVL Tree เมอมการน าขอมลเหลานเขา 5, 16, 22, 45, 2, 10, 18, 30,

50, 12, 1 4. จงออกแบบ class ทใชโครงสรางของ AVL Tree เปนตวเกบขอมลโดยมเงอนไขวา ในแต

ละ node ของ AVL Tree จะตองเปนการเปนค เชน (key, data) โดยการน าเขาและดงออกจะใช key เปนตวก าหนด สวน data เปนขอมลทเกบอยภายในหนวยความจ า ณ key ทก าหนดให (ด class TreeMap ของ Java ประกอบ)

5. จงเขยนโปรแกรมทดสอบการท างานของ AVL Tree โดยก าหนดใหน าขอมลเขาส AVL Tree เปนจ านวนเทากบ 10000 ตว (Integer หรอ String) หลงจากนนใหท าการจบเวลาการคนหาขอมลทอยใน node ทางดานซายสด และ node ทอยทางดานขวาสด

6. จงเขยนโปรแกรมทรบ Binary Search Tree เปนขอมลน าเขา และท าการเปลยน BST นให

เปน AVL Tree โดยก าหนดใหม method changeTree() เปนตวจดการ การท างานดงกลาว parameter ทตองสงไปให changeTree() คอ root node ของ BST และสงท changeTree() สงกลบออกมาคอ AVL Tree

7. ท าตรงกนขามกบโจทยในขอ 6 โดยเปลยนขอมลทน าเขาเปน AVL Tree และขอมลทได

กลบออกมาเปน BST

H

A C

D

E

B J F

L

I K G

M

Page 52: BST - FEUsci.feu.ac.th/faa/dsa/bookPDFs/chap7-SelfBalancedBST.pdfSelf-Balanced Binary Search Trees บทท 7 180 7.1.1 ความไม สมด ลของ node และ การหม

Self-Balanced Binary Search Trees บทท 7

228

8. จงเขยน method เพอใชในการนบ node ทเปน parent node ใน Red-Black Tree 9. จงเขยนรปของ Red-Black Tree ทมการน าขอมล A ถง K เขาพรอมทงวเคราะหถง

เหตการณทเกดข น 10. จงสราง Red-Black Tree สองตนจากขอมลแบบสม (random) 32 ตวพรอมทงวาดภาพ

ของ Tree ทเกดข น ใหท าการเปรยบเทยบกบ BST ทสรางขนจากขอมลเดยวกน 11. จงเขยนโปรแกรมทนบจ านวนเปอรเซนตของ node สด าใน Red-Black Tree ใหท าการ

ทดสอบดวยการน าขอมลแบบสมเขาจ านวน N ตวโดยเรมทดสอบท N = 103, 104, 105, และ 106

12. จงเขยน method ส าหรบการคนหา node ทก าหนดใหใน Red-Black Tree 13. การลบ node ออกจาก Red-Black Tree ของเราใชการแทนท node ดวย in-order

successor หรอทเรยกวาการแทนทดวย node ทมคานอยทสดทางขวา จงเขยน method ทแทนท node ทถกลบดวย node ทมคามากทสดทางซาย

14. จาก Red-black Tree ทใหจงแสดงขนตอนทเกดข นเมอลบ node 32 และ node 34

(ตามล าดบ)

15. จงแสดงภาพของ Red-Black tree หลงจากน าขอมลตงแต 'A' ไปจนถง 'M' เขาส tree และเมอลบ 'C', 'H', 'L' และ 'M' ออกจาก tree

16. จากโจทยในขอ 15 จงใชขอมลเดยวกนแสดงภาพของ Splay tree 17. การลบ node ออกจาก Splay tree ในตวอยางใช node ทมคานอยทสดทางขวามาแทน

node ทถกลบออก จงเขยน method delete() ทใช node ทมคามากทสดทางซายมาแทน

18. จงเขยน method ส าหรบการคนหา node ทมคานอยทสดใน Splay tree ดวยการใช

recursion 19. จงเขยน method ส าหรบการคนหา node ทมคามากทสดใน Splay tree ดวยการใช loop

34

28

32 17

19

60

54 65