数据结构的扩张

一.扩张数据结构

1.目的:给基本数据结构进行扩张以支持一些附加功能或者利用附加信息加速已有的操作

2.基本步骤(可以用于检查和纠错)

(1)选择一种基础的数据结构(红黑树,树,链表,队列等)

(2)确定基础数据结构中要维护的附加信息(具体数据,或属性,或指针类信息等)

(3)检验基础数据结构上的基本修改操作是否能维护附加信息(保证数据结构的运行效率)

(4)设计一些新的操作

 

二.动态顺序统计

1.顺序统计树:在每个结点上存储附加信息(以x为根的子树(包括x本身)的节点数size)的一棵红黑树

2.一个元素的秩为在中序遍历树时输出的位置

3.分析

(1)选择基础数据结构--红黑树

(2)添加节点附加信息--size

(3)保证删除,插入等操作都能在O(lg n)时间内维护size属性

(4)设计新的操作-select和rank

 查找具有给定秩的元素,

  1 class Node:
  2     def __init__(self, key, right, left, p, color, size):
  3         self.key = key
  4         self.right = right
  5         self.left = left
  6         self.p = p
  7         self.color = color
  8         self.size = size
  9 
 10 
 11 class tree:
 12     def __init__(self, root, nil):
 13         self.root = root
 14         self.nil = nil
 15 
 16     def tree_insert(self, z):
 17         y = self.nil
 18         x = self.root
 19         while x != self.nil:
 20             y = x
 21             if z.key < x.key:
 22                 x = x.left
 23             else:
 24                 x = x.right
 25         z.p = y
 26         if y == self.nil:
 27             self.root = z
 28         elif z.key < y.key:
 29             y.left = z
 30         else:
 31             y.right = z
 32         z.left = self.nil
 33         z.right = self.nil
 34         z.color = "RED"
 35         # z插入成功后,size初始化为1
 36         z.size = 1
 37         # 红黑树性质维护
 38         self.rb_insert_fixup(z)
 39         # 更新结点z的父结点直到根结点的size属性
 40         while z.p != self.nil:
 41             z.p.size += 1
 42             z = z.p
 43 
 44     def left_rotate(self, x):
 45         y = x.right
 46         x.right = y.left
 47         if y.left != self.nil:
 48             y.left.p = x
 49         y.p = x.p
 50         if x.p == self.nil:
 51             self.root = y
 52         elif x == x.p.left:
 53             x.p.left = y
 54         else:
 55             x.p.right = y
 56         y.left = x
 57         x.p = y
 58         # 左旋导致两个结点的size属性失效,size属性更新如下:
 59         y.size = x.size
 60         x.size = x.left.size + x.right.size + 1
 61 
 62     def right_rotate(self, y):
 63         x = y.left
 64         y.left = x.right
 65         if x.right != self.nil:
 66             x.right.p = y
 67         x.p = y.p
 68         if y.p == self.nil:
 69             self.root = x
 70         elif y == y.p.left:
 71             y.p.left = x
 72         else:
 73             y.p.right = x
 74         x.right = y
 75         y.p = x
 76         # 右旋导致两个结点的size属性失效,size属性更新如下:
 77         x.size = y.size
 78         y.size = y.right.size + y.left.size + 1
 79 
 80     def rb_insert_fixup(self, z):
 81         while z.p.color == "RED":
 82             if z.p == z.p.p.left:
 83                 y = z.p.p.right
 84                 if y.color == "RED":
 85                     z.p.color = "BLACK"
 86                     y.color = "BLACK"
 87                     z.p.p.color = "RED"
 88                     z = z.p.p
 89                 else:
 90                     if z == z.p.right:
 91                         z = z.p
 92                         self.left_rotate(z)
 93                     z.p.color = "BLACK"
 94                     z.p.p.color = "RED"
 95                     self.right_rotate(z.p.p)
 96             else:
 97                 y = z.p.p.left
 98                 if y.color == "RED":
 99                     z.p.color = "BLACK"
100                     y.color = "BLACK"
101                     z.p.p.color = "RED"
102                     z = z.p.p
103                 else:
104                     if z == z.p.left:
105                         z = z.p
106                         self.right_rotate(z)
107                     z.p.color = "BLACK"
108                     z.p.p.color = "RED"
109                     self.left_rotate(z.p.p)
110         self.root.color = "BLACK"
111 
112     def inorder_tree_walk(self, x):
113         if x != self.nil:
114             self.inorder_tree_walk(x.left)
115             print(x.key)
116             self.inorder_tree_walk(x.right)
117 
118     def tree_search(self, x, k):
119         if x == self.nil or k == x.key:
120             return x
121         if k < x.key:
122             return self.tree_search(x.left, k)
123         else:
124             return self.tree_search(x.right, k)
125 
126     def rb_transplant(self, u, v):
127         if u.p == self.nil:
128             self.root = v
129         elif u == u.p.left:
130             u.p.left = v
131         else:
132             u.p.right = v
133         v.p = u.p
134 
135     def tree_minimum(self, x):
136         while x.left != self.nil:
137             x = x.left
138         return x
139 
140     def rb_delete(self, z):
141         y = z
142         y_original_color = y.color
143         if z.left == self.nil:
144             x = z.right
145             self.rb_transplant(z, z.right)
146         elif z.right == self.nil:
147             x = z.left
148             self.rb_transplant(z, z.left)
149         else:
150             y = self.tree_minimum(z.right)
151             y_original_color = y.color
152             x = y.right
153             if y.p == z:
154                 x.p = y
155             else:
156                 self.rb_transplant(y, y.right)
157                 y.right = z.right
158                 y.right.p = y
159             self.rb_transplant(z, y)
160             y.left = z.left
161             y.left.p = y
162             y.color = z.color
163             if y_original_color == "BLACK":
164                 self.rb_delete_fixup(x)
165 
166     def rb_delete_fixup(self, x):
167         while x != self.root and x.color == "BLACK":
168             if x == x.p.left:
169                 w = x.p.right
170                 if w.color == "RED":
171                     w.color = "BLACK"
172                     x.p.color = "RED"
173                     self.left_rotate(x.p)
174                     w = x.p.right
175                 if w.left.color == "BLACK" and w.right.color == "BLACK":
176                     w.color = "RED"
177                     x = x.p
178                 else:
179                     if w.right.color == "BLACK":
180                         w.left.color == "BLACK"
181                         w.color = "RED"
182                         self.right_rotate(w)
183                         w = x.p.right
184                     w.color = x.p.color
185                     x.p.color = "BLACK"
186                     w.right.color = "BLACK"
187                     self.left_rotate(x.p)
188                     x = self.root
189             else:
190                 w = x.p.left
191                 if w.color == "RED":
192                     w.color = "BLACK"
193                     x.p.color = "RED"
194                     self.right_rotate(x.p)
195                     w = x.p.left
196                 if w.right.color == "BLACK" and w.left.color == "BLACK":
197                     w.color = "RED"
198                     x = x.p
199                 else:
200                     if w.left.color == "BLACK":
201                         w.right.color == "BLACK"
202                         w.color = "RED"
203                         self.left_rotate(w)
204                         w = x.p.left
205                     w.color = x.p.color
206                     x.p.color = "BLACK"
207                     w.left.color = "BLACK"
208                     self.right_rotate(x.p)
209                     x = self.root
210         x.color = "BLACK"
211 
212     def print_tree(self, z):
213         if z != self.nil:
214             print(z.key, z.color, ":", end='')
215             print("( ", end='')
216             print(z.left.key, z.left.color, "   ", end='')
217             print(z.right.key, z.right.color, end='')
218             print(" )", end='')
219 
220     # 找出统计树中的第i小的关键字
221     def os_select(self, x, i):
222         r = x.left.size + 1
223         if i == r:
224             return x
225         elif x < r:
226             return self.os_select(x.left, i)
227         else:
228             # 注意这种情况就应该找以x为根结点的右子树中第i-r小的关键字了。
229             return self.os_select(x.right, i - r)
230 
231     # 确定一个元素的秩:返回对T中序遍历对应的线性序中x的位置
232     def os_rank(self, x):
233         r = x.left.size + 1
234         y = x
235         while y != self.root:
236             if y == y.p.right:
237                 r += y.p.left.size + 1
238             y = y.p
239         return r
动态顺序统计

 

 

三.区间树

1.区间树是对动态集合进行维护的红黑树,其中每个元素x都包含一个区间x.int

fe

2.分析:

(1)选择基础数据结构--红黑树

(2)添加节点附加信息--以x为根的子树中所有区间的端点的最大值x.max

(3)对信息的维护--插入和删除操作能否在O(lgn)时间内完成

(4)设计新的操作-insert,delete,search

  1 class Node:
  2     def __init__(self,right,left,p,color,inter,maxx):
  3         self.key=inter.low
  4         self.right=right
  5         self.left=left
  6         self.p=p
  7         self.color=color
  8         #新增区间属性
  9         self.inter=inter
 10         #新增附加信息maxx
 11         self.maxx=maxx
 12  
 13 #代表区间的类
 14 class Inter:
 15     def __init__(self,low,high):
 16         self.low=low
 17         self.high=high
 18  
 19 class tree:
 20     def __init__(self,root,nil):
 21         self.root=root
 22         self.nil=nil
 23     def tree_insert(self,z):
 24         y=self.nil
 25         x=self.root
 26         while x!=self.nil:
 27             y=x
 28             if z.key<x.key:
 29                 x=x.left
 30             else:
 31                 x=x.right
 32         z.p=y
 33         if y==self.nil:
 34             self.root=z
 35         elif z.key<y.key:
 36             y.left=z
 37         else:
 38             y.right=z
 39         z.left=self.nil
 40         z.right=self.nil
 41         z.color="RED"
 42         z.maxx=max(z.inter.high,z.left.maxx,z.right.maxx)
 43         #红黑树性质维护
 44         self.rb_insert_fixup(z)
 45         #更新父结点直到根结点的maxx
 46         while z.p!=self.nil:
 47             z.p.maxx=max(z.p.maxx,z.maxx)
 48             z=z.p
 49             
 50     def left_rotate(self,x):
 51         y=x.right
 52         x.right=y.left
 53         if y.left!=self.nil:
 54             y.left.p=x
 55         y.p=x.p
 56         if x.p==self.nil:
 57             self.root=y
 58         elif x==x.p.left:
 59             x.p.left=y
 60         else:
 61             x.p.right=y
 62         y.left=x
 63         x.p=y
 64         #左旋导致两个结点的max属性改变,更新如下
 65         y.maxx=x.maxx
 66         x.maxx=max(x.left.maxx,x.right.maxx,x.inter.high)
 67         
 68  
 69     def right_rotate(self,y):
 70         x=y.left
 71         y.left=x.right
 72         if x.right!=self.nil:
 73             x.right.p=y
 74         x.p=y.p  
 75         if y.p==self.nil:
 76             self.root=x
 77         elif y==y.p.left:
 78             y.p.left=x
 79         else:
 80             y.p.right=x
 81         x.right=y
 82         y.p=x
 83         #右旋导致两个结点的max属性改变,更新如下
 84         x.maxx=y.maxx
 85         y.maxx=max(y.right.maxx,y.left.maxx,y.inter.high)
 86  
 87     def rb_insert_fixup(self,z):
 88         while z.p.color=="RED":
 89             if z.p==z.p.p.left:
 90                 y=z.p.p.right
 91                 if y.color=="RED":
 92                     z.p.color="BLACK"
 93                     y.color="BLACK"
 94                     z.p.p.color="RED"
 95                     z=z.p.p
 96                 else:
 97                     if z==z.p.right:
 98                         z=z.p
 99                         self.left_rotate(z)
100                     z.p.color="BLACK"
101                     z.p.p.color="RED"
102                     self.right_rotate(z.p.p)
103             else:
104                 y=z.p.p.left
105                 if y.color=="RED":
106                     z.p.color="BLACK"
107                     y.color="BLACK"
108                     z.p.p.color="RED"
109                     z=z.p.p
110                 else:
111                     if z==z.p.left:
112                         z=z.p
113                         self.right_rotate(z)
114                     z.p.color="BLACK"
115                     z.p.p.color="RED"
116                     self.left_rotate(z.p.p)
117         self.root.color="BLACK"
118     def inorder_tree_walk(self,x):
119         if x!=self.nil:
120             self.inorder_tree_walk(x.left)
121             print(x.key)
122             self.inorder_tree_walk(x.right)
123     def tree_search(self,x,k):
124         if x==self.nil or k==x.key:
125             return x
126         if k < x.key:
127             return self.tree_search(x.left,k)
128         else: return self.tree_search(x.right,k)
129  
130     def rb_transplant(self,u,v):
131         if u.p==self.nil:
132             self.root=v
133         elif u==u.p.left:
134             u.p.left=v
135         else:
136             u.p.right=v
137         v.p=u.p
138     def tree_minimum(self,x):
139         while x.left!=self.nil:
140             x=x.left
141         return x
142  
143     
144     def rb_delete(self,z):
145         y=z
146         y_original_color=y.color
147         if z.left==self.nil:
148             x=z.right
149             self.rb_transplant(z,z.right)
150         elif z.right==self.nil:
151             x=z.left
152             self.rb_transplant(z,z.left)
153         else:
154             y=self.tree_minimum(z.right)
155             y_original_color=y.color
156             x=y.right
157             if y.p==z:
158                 x.p=y
159             else:
160                 self.rb_transplant(y,y.right)
161                 y.right=z.right
162                 y.right.p=y
163             self.rb_transplant(z,y)
164             y.left=z.left
165             y.left.p=y
166             y.color=z.color
167             if y_original_color=="BLACK":
168                 self.rb_delete_fixup(x)       
169             
170  
171     def rb_delete_fixup(self,x):
172         while x!=self.root and x.color=="BLACK":
173             if x==x.p.left:
174                 w=x.p.right
175                 if w.color=="RED":
176                     w.color="BLACK"
177                     x.p.color="RED"
178                     self.left_rotate(x.p)
179                     w=x.p.right
180                 if w.left.color=="BLACK" and w.right.color=="BLACK":
181                     w.color="RED"
182                     x=x.p
183                 else:
184                     if w.right.color=="BLACK":
185                         w.left.color=="BLACK"
186                         w.color="RED"
187                         self.right_rotate(w)
188                         w=x.p.right
189                     w.color=x.p.color
190                     x.p.color="BLACK"
191                     w.right.color="BLACK"
192                     self.left_rotate(x.p)
193                     x=self.root
194             else:
195                 w=x.p.left
196                 if w.color=="RED":
197                     w.color="BLACK"
198                     x.p.color="RED"
199                     self.right_rotate(x.p)
200                     w=x.p.left
201                 if w.right.color=="BLACK" and w.left.color=="BLACK":
202                     w.color="RED"
203                     x=x.p
204                 else:
205                     if w.left.color=="BLACK":
206                         w.right.color=="BLACK"
207                         w.color="RED"
208                         self.left_rotate(w)
209                         w=x.p.left
210                     w.color=x.p.color
211                     x.p.color="BLACK"
212                     w.left.color="BLACK"
213                     self.right_rotate(x.p)
214                     x=self.root
215         x.color="BLACK"
216  
217     def print_tree(self,z):
218         if z!=self.nil:
219             print(z.key,z.color,"[",z,inter.low,",",z.inter.high,"]",":",end='')
220             print("( ",end='')
221             print(z.left.key,z.left.color,"   ",end='')
222             print(z.right.key,z.right.color,end='')
223             print(" )",end='')
224     def interval_search(self,i):
225         x=self.root
226         while x!=self.nil and (i.high<x.inter.low or x.inter.high<i.low):
227             if x.left!=self.nil and x.left.maxx>=i.low:
228                 x=x.left
229             else:
230                 x=x.right
231         return x
232  
233 if __name__=="__main__":
234     inter=Inter(0,0)
235     nil=Node(None,None,None,"BLACK",inter,0)
236     inter=Inter(16,21)
237     root=Node(nil,nil,nil,"BLACK",inter,21)
238     t=tree(root,nil)
239     TT=[8,9,25,30,5,8,15,23,17,19,26,26,0,3,6,10,19,20]
240     for i in range(0,len(TT),2):
241         inter=Inter(TT[i],TT[i+1])
242         z=Node(nil,nil,nil,"RED",inter,0)
243         t.tree_insert(z)
区间树

 

posted on 2018-07-26 15:46  温润有方  阅读(344)  评论(0编辑  收藏  举报