您的位置:首页 > 理论基础 > 数据结构算法

[从头学数学] 第258节 Python实现数据结构:伸展树(splay tree)

2016-09-07 08:41 363 查看
剧情提要:
阿伟看到了一本比较有趣的书,是关于《计算几何》的,2008年由北清派出版。很好奇
它里面讲了些什么,就来看看啦。

正剧开始:

星历2016年09月07日 08:41:50, 银河系厄尔斯星球中华帝国江南行省。
[工程师阿伟]正在和[机器小伟]一起研究[计算几何]]。





#
###
# @usage splayTree(伸展树),具有根元素记忆及动态调整功能的二叉搜索树
# @author mw
# @date 2016年09月07日 星期三 08:37:17
# @param
# @return
#
###
class SplayTree(object):
class __SplayNode(object):
def __init__(self, key, left = None, right = None):
self.key=key
self.left=left
self.right=right

def __iter__(self):
if self.left != None:
for elem in self.left:
yield elem

if (self.key != None):
yield self.key

if self.right != None:
for elem in self.right:
yield elem

#迭代的是Node类型,用于删除结点
def iternodes(self):
if self.left != None:
for elem in self.left.iternodes():
yield elem

if self != None and self.key != None:
yield self

if self.right != None:
for elem in self.right.iternodes():
yield elem

def info(self):
s = 'Key='+str(self.key)+', '+\
'LChild='+str(self.left)+', '+\
'RChild='+str(self.right);
print(s);

def __str__(self):
return str(self.key);

def __repr__(self):
if self != None:
s_1 = str(self.key);
else:
s_1 = 'None';

if self.left != None:
s_2 = str(self.left.key);
else:
s_2 = 'None';

if self.right != None:
s_3 = str(self.right.key);
else:
s_3 = 'None';

return '__SplayNode('+s_1+', ' + s_2 +', ' + s_3 +')';

def __init__(self):
self.root=None
self.header = SplayTree.__SplayNode(None) #For splay()

#LL
def singleLeftRotate(self,node):
k1=node.left
node.left=k1.right
k1.right=node
return k1

#RR
def singleRightRotate(self,node):
k1=node.right
node.right=k1.left
k1.left=node
return k1

#RL
def doubleLeftRotate(self,node):
node.left=self.singleRightRotate(node.left)
return self.singleLeftRotate(node)

#LR
def doubleRightRotate(self,node):
node.right=self.singleLeftRotate(node.right)
return self.singleRightRotate(node)

#伸展运动
def splay(self, key):
l = r = self.header
t = self.root
if t is None:
return

self.header.left = self.header.right = None

while True:
if key < t.key:
if t.left == None:
break;
if key < t.left.key:
t = self.singleLeftRotate(t);
if t.left == None:
break;
r.left = t
r = t
t = t.left

elif key > t.key:
if t.right == None:
break;
if key > t.right.key:
t = self.singleRightRotate(t);
if t.right == None:
break;
l.right = t
l = t
t = t.right
else:
break;

l.right = t.left
r.left = t.right
t.left = self.header.right
t.right = self.header.left
self.root = t

#
#和splay操作捆绑的方法
#

#插入
def insert(self, key):
if (self.root == None):
self.root = SplayTree.__SplayNode(key)
return

self.splay(key)
if self.root.key == key:
# If the key is already there in the tree, don't do anything.
return

n = SplayTree.__SplayNode(key)
if key < self.root.key:
n.left = self.root.left
n.right = self.root
self.root.left = None
else:
n.right = self.root.right
n.left = self.root
self.root.right = None
self.root = n

def remove(self, key):
self.splay(key)
if self.root is None or key != self.root.key:
return None;

# Now delete the root.
if self.root.left== None:
self.root = self.root.right
else:
x = self.root.right
self.root = self.root.left
self.splay(key)
self.root.right = x

return key;

def findMin(self):
if self.root == None:
return None
x = self.root
while x.left != None:
x = x.left
self.splay(x.key)
return x.key

def findMax(self):
if self.root == None:
return None
x = self.root
while (x.right != None):
x = x.right
self.splay(x.key)
return x.key

def find(self, key):
if self.root == None:
return None
self.splay(key)
if self.root.key != key:
return None
return self.root.key

def isEmpty(self):
return self.root == None

#
#结构信息查询,不与splay操作捆绑
#

def getRoot(self):
return repr(self.root);

def info(self):
a = [];
for x in self:
a.append(x);

print(a);

def __iter__(self):
if self.root != None:
return self.root.__iter__()
else:
return [].__iter__()

def __contains__(self, val):
for x in self:
if (x == val):
return True;

return False;

def __len__(self):
a = [];
for x in self:
a.append(x);

return len(a);

#求结点高度
def height(self, node):
if (node == None):
return 0;
else:
m = self.height(node.left);
n = self.height(node.right);
return max(m, n)+1;

#传回结点的原始信息
def iternodes(self):
if self.root != None:
return self.root.iternodes()
else:
return [None];

#寻找节点路径
def findNodePath(self, root, node):
path = [];
if root == None or root.key == None:
path = [];
return path

while (root != node):
if node.key < root.key:
path.append(root);
root = root.left;
elif node.key >= root.key:
path.append(root);
root = root.right;
else:
break;

path.append(root);
return path;

#寻找父结点
def parent(self, root, node):
path = self.findNodePath(root, node);
if (len(path)>1):
return path[-2];
else:
return None;

#是否左孩子
def isLChild(self, parent, lChild):
if (parent.getLeft() != None and parent.getLeft() == lChild):
return True;

return False;

#是否右孩子
def isRChild(self, parent, rChild):
if (parent.getRight() != None and parent.getRight() == rChild):
return True;

return False;

#求某元素是在树的第几层
#约定根为0层
#这个计算和求结点的Height是不一样的
def level(self, elem):
if self.root != None:
node = self.root;
lev = 0;

while (node != None):
if elem < node.key:
node = node.left;
lev+=1;
elif elem > node.key:
node = node.right;
lev+=1;
else:
return lev;

return -1;

else:
return -1;

#

用例:
#
if __name__ == '__main__':
splay = SplayTree();

a = [20, 30, 40, 120, 13, 39, 38, 40, 18, 101];

for item in a:
splay.insert(item);
print(splay.getRoot());
print(splay.height(splay.root));

splay.info();
print(len(splay));

for node in splay.iternodes():
print(splay.findNodePath(splay.root, node), '\n');

'''
for item in reversed(a):
print('remove:', splay.remove(item));
splay.getRoot();
print(splay.height(splay.root));

'''

print(splay.findMax());
print(splay.getRoot());

>>>
__SplayNode(20, None, None)
1
__SplayNode(30, 20, None)
2
__SplayNode(40, 30, None)
3
__SplayNode(120, 40, None)
4
__SplayNode(13, None, 20)
4
__SplayNode(39, 30, 40)
4
__SplayNode(38, 30, 39)
4
__SplayNode(40, 39, 120)
6
__SplayNode(18, 13, 39)
4
__SplayNode(101, 39, 120)
5
[13, 18, 20, 30, 38, 39, 40, 101, 120]
9
[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(18, 13, 30), __SplayNode(13, None, None)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(18, 13, 30)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(18, 13, 30), __SplayNode(30, 20, 38), __SplayNode(20, None, None)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(18, 13, 30), __SplayNode(30, 20, 38)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(18, 13, 30), __SplayNode(30, 20, 38), __SplayNode(38, None, None)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40)]

[__SplayNode(101, 39, 120), __SplayNode(39, 18, 40), __SplayNode(40, None, None)]

[__SplayNode(101, 39, 120)]

[__SplayNode(101, 39, 120), __SplayNode(120, None, None)]

120
__SplayNode(120, 101, None)

#
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: