| 
									
										
										
										
											2024-09-20 19:24:32 +08:00
										 |  |  | /* | 
					
						
							|  |  |  | 文件名:RedBlackTreeClass.nut | 
					
						
							|  |  |  | 路径:Dps_A/BaseClass/RedBlackTreeClass/RedBlackTreeClass.nut | 
					
						
							|  |  |  | 创建日期:2024-09-19	12:42 | 
					
						
							|  |  |  | 文件用途:红黑树类 | 
					
						
							|  |  |  | */ | 
					
						
							|  |  |  | // 红黑树节点类 | 
					
						
							|  |  |  | class RBTreeNode { | 
					
						
							|  |  |  |     key = null; | 
					
						
							|  |  |  |     time = null; | 
					
						
							|  |  |  |     left = null; | 
					
						
							|  |  |  |     right = null; | 
					
						
							|  |  |  |     parent = null; | 
					
						
							|  |  |  |     color = null; | 
					
						
							|  |  |  |     Info = null; | 
					
						
							|  |  |  |     constructor(key, func_info) { | 
					
						
							|  |  |  |         this.key = key; | 
					
						
							|  |  |  |         this.time = key; | 
					
						
							|  |  |  |         this.Info = func_info; | 
					
						
							|  |  |  |         this.left = null; | 
					
						
							|  |  |  |         this.right = null; | 
					
						
							|  |  |  |         this.parent = null; | 
					
						
							|  |  |  |         this.color = "red"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function _tyoeof() { | 
					
						
							|  |  |  |         return "RBTreeNode"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | // 红黑树类 | 
					
						
							|  |  |  | class RedBlackTree { | 
					
						
							|  |  |  |     nil = null; | 
					
						
							|  |  |  |     root = null; | 
					
						
							|  |  |  |     size = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function _tyoeof() { | 
					
						
							|  |  |  |         return "RedBlackTree"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor() { | 
					
						
							|  |  |  |         this.nil = RBTreeNode(null, null); | 
					
						
							|  |  |  |         this.root = this.nil; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function insert(key, func_info) { | 
					
						
							|  |  |  |         local z = RBTreeNode(key, func_info); | 
					
						
							|  |  |  |         local y = this.nil; | 
					
						
							|  |  |  |         local x = this.root; | 
					
						
							|  |  |  |         while (x != this.nil) { | 
					
						
							|  |  |  |             y = x; | 
					
						
							|  |  |  |             if (z.key< x.key) { | 
					
						
							|  |  |  |                 x = x.left; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 x = x.right; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         z.parent = y; | 
					
						
							|  |  |  |         if (y == this.nil) { | 
					
						
							|  |  |  |             this.root = z; | 
					
						
							|  |  |  |         } else if (z.key< y.key) { | 
					
						
							|  |  |  |             y.left = z; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             y.right = z; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         z.left = this.nil; | 
					
						
							|  |  |  |         z.right = this.nil; | 
					
						
							|  |  |  |         z.color = "red"; | 
					
						
							|  |  |  |         this.insertFixup(z); | 
					
						
							|  |  |  |         this.size++; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function insertFixup(z) { | 
					
						
							|  |  |  |         while (z.parent.color == "red") { | 
					
						
							|  |  |  |             if (z.parent.parent && z.parent == z.parent.parent.left) { | 
					
						
							|  |  |  |                 local y = z.parent.parent.right; | 
					
						
							|  |  |  |                 if (y.color == "red") { | 
					
						
							|  |  |  |                     z.parent.color = "black"; | 
					
						
							|  |  |  |                     y.color = "black"; | 
					
						
							|  |  |  |                     z.parent.parent.color = "red"; | 
					
						
							|  |  |  |                     z = z.parent.parent; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     if (z == z.parent.right) { | 
					
						
							|  |  |  |                         z = z.parent; | 
					
						
							|  |  |  |                         this.leftRotate(z); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     z.parent.color = "black"; | 
					
						
							|  |  |  |                     z.parent.parent.color = "red"; | 
					
						
							|  |  |  |                     this.rightRotate(z.parent.parent); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 if (z.parent.parent && z.parent.parent.left.color == "red") { | 
					
						
							|  |  |  |                     z.parent.color = "black"; | 
					
						
							|  |  |  |                     z.parent.parent.left.color = "black"; | 
					
						
							|  |  |  |                     z.parent.parent.color = "red"; | 
					
						
							|  |  |  |                     z = z.parent.parent; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     if (z == z.parent.left) { | 
					
						
							|  |  |  |                         z = z.parent; | 
					
						
							|  |  |  |                         this.rightRotate(z); | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     z.parent.color = "black"; | 
					
						
							|  |  |  |                     if (z.parent.parent) z.parent.parent.color = "red"; | 
					
						
							|  |  |  |                     this.leftRotate(z.parent.parent); | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this.root.color = "black"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function leftRotate(x) { | 
					
						
							|  |  |  |         if (!x) return; | 
					
						
							|  |  |  |         local y = x.right; | 
					
						
							|  |  |  |         x.right = y.left; | 
					
						
							|  |  |  |         if (y.left != this.nil) { | 
					
						
							|  |  |  |             y.left.parent = x; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         y.parent = x.parent; | 
					
						
							|  |  |  |         if (x.parent == this.nil) { | 
					
						
							|  |  |  |             this.root = y; | 
					
						
							|  |  |  |         } else if (x == x.parent.left) { | 
					
						
							|  |  |  |             x.parent.left = y; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             x.parent.right = y; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         y.left = x; | 
					
						
							|  |  |  |         x.parent = y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function rightRotate(x) { | 
					
						
							|  |  |  |         local y = x.left; | 
					
						
							|  |  |  |         x.left = y.right; | 
					
						
							|  |  |  |         if (y.right != this.nil) { | 
					
						
							|  |  |  |             y.right.parent = x; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         y.parent = x.parent; | 
					
						
							|  |  |  |         if (x.parent == this.nil) { | 
					
						
							|  |  |  |             this.root = y; | 
					
						
							|  |  |  |         } else if (x == x.parent.left) { | 
					
						
							|  |  |  |             x.parent.left = y; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             x.parent.right = y; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         y.right = x; | 
					
						
							|  |  |  |         x.parent = y; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function minimum(...) { | 
					
						
							|  |  |  |         local node = this.root; | 
					
						
							|  |  |  |         if (vargv.len() > 0) node = vargv[0]; | 
					
						
							|  |  |  |         while (node.left != this.nil) { | 
					
						
							|  |  |  |             node = node.left; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return node; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function transplant(u, v) { | 
					
						
							|  |  |  |         if (u.parent == this.nil) { | 
					
						
							|  |  |  |             this.root = v; | 
					
						
							|  |  |  |         } else if (u == u.parent.left) { | 
					
						
							|  |  |  |             u.parent.left = v; | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             u.parent.right = v; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         v.parent = u.parent; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function deleteFixup(x) { | 
					
						
							|  |  |  |         while (x != this.root && x.color == "black") { | 
					
						
							|  |  |  |             if (x == x.parent.left) { | 
					
						
							|  |  |  |                 local w = x.parent.right; | 
					
						
							|  |  |  |                 if (w.color == "red") { | 
					
						
							|  |  |  |                     w.color = "black"; | 
					
						
							|  |  |  |                     x.parent.color = "red"; | 
					
						
							|  |  |  |                     this.leftRotate(x.parent); | 
					
						
							|  |  |  |                     w = x.parent.right; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (w.left.color == "black" && w.right.color == "black") { | 
					
						
							|  |  |  |                     w.color = "red"; | 
					
						
							|  |  |  |                     x = x.parent; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     if (w.right.color == "black") { | 
					
						
							|  |  |  |                         w.left.color = "black"; | 
					
						
							|  |  |  |                         w.color = "red"; | 
					
						
							|  |  |  |                         this.rightRotate(w); | 
					
						
							|  |  |  |                         w = x.parent.right; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     w.color = x.parent.color; | 
					
						
							|  |  |  |                     x.parent.color = "black"; | 
					
						
							|  |  |  |                     w.right.color = "black"; | 
					
						
							|  |  |  |                     this.leftRotate(x.parent); | 
					
						
							|  |  |  |                     x = this.root; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 local w = x.parent.left; | 
					
						
							|  |  |  |                 if (w.color == "red") { | 
					
						
							|  |  |  |                     w.color = "black"; | 
					
						
							|  |  |  |                     x.parent.color = "red"; | 
					
						
							|  |  |  |                     this.rightRotate(x.parent); | 
					
						
							|  |  |  |                     w = x.parent.left; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |                 if (w.right.color == "black" && w.left.color == "black") { | 
					
						
							|  |  |  |                     w.color = "red"; | 
					
						
							|  |  |  |                     x = x.parent; | 
					
						
							|  |  |  |                 } else { | 
					
						
							|  |  |  |                     if (w.left.color == "black") { | 
					
						
							|  |  |  |                         w.right.color = "black"; | 
					
						
							|  |  |  |                         w.color = "red"; | 
					
						
							|  |  |  |                         this.leftRotate(w); | 
					
						
							|  |  |  |                         w = x.parent.left; | 
					
						
							|  |  |  |                     } | 
					
						
							|  |  |  |                     w.color = x.parent.color; | 
					
						
							|  |  |  |                     x.parent.color = "black"; | 
					
						
							|  |  |  |                     w.left.color = "black"; | 
					
						
							|  |  |  |                     this.rightRotate(x.parent); | 
					
						
							|  |  |  |                     x = this.root; | 
					
						
							|  |  |  |                 } | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         x.color = "black"; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function deleteNode(z) { | 
					
						
							|  |  |  |         local y = z; | 
					
						
							|  |  |  |         local yOriginalColor = y.color; | 
					
						
							|  |  |  |         local x; | 
					
						
							|  |  |  |         if (z.left == this.nil) { | 
					
						
							|  |  |  |             x = z.right; | 
					
						
							|  |  |  |             this.transplant(z, z.right); | 
					
						
							|  |  |  |         } else if (z.right == this.nil) { | 
					
						
							|  |  |  |             x = z.left; | 
					
						
							|  |  |  |             this.transplant(z, z.left); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |             y = this.minimum(z.right); | 
					
						
							|  |  |  |             yOriginalColor = y.color; | 
					
						
							|  |  |  |             x = y.right; | 
					
						
							|  |  |  |             if (y.parent == z) { | 
					
						
							|  |  |  |                 x.parent = y; | 
					
						
							|  |  |  |             } else { | 
					
						
							|  |  |  |                 this.transplant(y, y.right); | 
					
						
							|  |  |  |                 y.right = z.right; | 
					
						
							|  |  |  |                 y.right.parent = y; | 
					
						
							|  |  |  |             } | 
					
						
							|  |  |  |             this.transplant(z, y); | 
					
						
							|  |  |  |             y.left = z.left; | 
					
						
							|  |  |  |             y.left.parent = y; | 
					
						
							|  |  |  |             y.color = z.color; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         if (yOriginalColor == "black") { | 
					
						
							|  |  |  |             this.deleteFixup(x); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this.size--; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function inorderTraversal(...) { | 
					
						
							|  |  |  |         local node = this.root; | 
					
						
							|  |  |  |         if (vargv.len() > 0) node = vargv[0]; | 
					
						
							|  |  |  |         if (node == this.nil) { | 
					
						
							|  |  |  |             return; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         this.inorderTraversal(node.left); | 
					
						
							|  |  |  |         print(node.key + "(" + node.color + ") "); | 
					
						
							|  |  |  |         this.inorderTraversal(node.right); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function getSize() { | 
					
						
							|  |  |  |         return this.size; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     function pop() { | 
					
						
							|  |  |  |         if (this.size <= 0) return null; | 
					
						
							|  |  |  |         local z = this.minimum(); | 
					
						
							|  |  |  |         if (z != this.nil) { | 
					
						
							|  |  |  |             this.deleteNode(z); | 
					
						
							|  |  |  |             return z; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-10-27 15:32:44 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     function GetPop() { | 
					
						
							|  |  |  |         if (this.size <= 0) return null; | 
					
						
							|  |  |  |         local z = this.minimum(); | 
					
						
							|  |  |  |         if (z != this.nil) { | 
					
						
							|  |  |  |             return z; | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |         return null; | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2024-09-20 19:24:32 +08:00
										 |  |  | } |