AVL树的pyhton实现
用cProfile做了统计,
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 0.074 0.074 <string>:1(<module>)
332 0.001 0.000 0.002 0.000 AVL_recurive_profile.py:103(LL_SingleRotate)
1001 0.001 0.000 0.001 0.000 AVL_recurive_profile.py:11(__init__)
307 0.001 0.000 0.001 0.000 AVL_recurive_profile.py:112(RR_SingleRotate)
97 0.000 0.000 0.001 0.000 AVL_recurive_profile.py:121(LR_DoubleRotate)
129 0.000 0.000 0.001 0.000 AVL_recurive_profile.py:125(RL_DoubleRotate)
1 0.003 0.003 0.074 0.074 AVL_recurive_profile.py:157(insert_profile)
1 0.000 0.000 0.000 0.000 AVL_recurive_profile.py:20(__init__)
58432 0.011 0.000 0.011 0.000 AVL_recurive_profile.py:66(get_hight)
14469/1000 0.044 0.000 0.062 0.000 AVL_recurive_profile.py:72(avl_insert)
1000 0.002 0.000 0.004 0.000 random.py:170(randrange)
1000 0.001 0.000 0.005 0.000 random.py:214(randint)
1000 0.001 0.000 0.002 0.000 random.py:220(_randbelow)
1 0.000 0.000 0.074 0.074 {built-in method exec}
15747 0.005 0.000 0.005 0.000 {built-in method max}
1000 0.003 0.000 0.003 0.000 {built-in method print}
1000 0.000 0.000 0.000 0.000 {method 'bit_length' of 'int' objects}
1 0.000 0.000 0.000 0.000 {method 'disable' of '_lsprof.Profiler' objects}
1358 0.000 0.000 0.000 0.000 {method 'getrandbits' of '_random.Random' objects}
代码如下:
#!/usr/bin/python
#coding=utf-8
from Trie.Trie_classic import ClassicTrie
# import Trie.ClassicTrie
import cProfile
import random
import sys
sys.setrecursionlimit(10000)
class Node:
def __init__(self, data=None, left=None, right=None,hierarchy=0,hight=0):
self.data = data
self.right = left
self.left = right
self.hierarchy = hierarchy
self.hight = hight
class AVL_Trie(ClassicTrie):
#init root
def __init__ (self,root=None):
self.root=root
self.root.hight=0
self.root.hierarchy=0
#
# def find(self,cmp_data,find_list=[]):
# # return node_list
# def compara(start_node,cmp_data):
# find_list.append(start_node)
# if start_node.data == cmp_data:
# return start_node
# elif start_node.data > cmp_data and start_node.right != None:
# return compara(start_node.right, cmp_data)
# elif start_node.data < cmp_data and start_node.left != None:
# return compara(start_node.left, cmp_data)
# else:
# raise ValueError
#
# return compara(self.root,cmp_data)
#
# def find_rtree_min(self,start_node):
# # return node_list
# def sub_findmin(start_node):
# if start_node.right == None:
# return start_node
# else:
# return sub_findmin(start_node.right)
#
# return sub_findmin(start_node.left)
#
def PreOrderTraverse(self,trace_node):
tracelist=[]
def sub_PreTr(node_list):
if node_list:
tracelist.append(node_list)
#print (node_list.data,end=',')
sub_PreTr(node_list.left)
sub_PreTr(node_list.right)
sub_PreTr(trace_node)
return tracelist
def get_hight(self,node):
if node==None :
return -1
else:
return node.hight
def avl_insert(self,ins_node,ins_location):
if(ins_location==None):
ins_location=ins_node
elif ins_node.data<ins_location.data:
ins_location.left=self.avl_insert(ins_node,ins_location.left)
if(self.get_hight(ins_location.left)-self.get_hight(ins_location.right)==2):
#unablance ins_location
if(ins_node.data<ins_location.left.data):
#LL
ins_location=self.LL_SingleRotate(ins_location)
else:
#LR
ins_location=self.LR_DoubleRotate(ins_location)
elif ins_node.data>ins_location.data:
ins_location.right=self.avl_insert(ins_node,ins_location.right)
if(self.get_hight(ins_location.right)-self.get_hight(ins_location.left)==2):
#unablance ins_location
if(ins_node.data>ins_location.right.data):
#RR
ins_location=self.RR_SingleRotate(ins_location)
else:
#RL
ins_location=self.RL_DoubleRotate(ins_location)
# else:
# print(ins_node.data,"already exist")
# raise ValueError
ins_location.hight=max(self.get_hight(ins_location.right),self.get_hight(ins_location.left))+1
ins_node.hierarchy=ins_location.hierarchy+1
return ins_location
def LL_SingleRotate(self,k2):
#update root return new root_node
k1=k2.left
k2.left=k1.right
k1.right=k2
k2.hight=max(self.get_hight(k2.left), self.get_hight(k2.right))+1
k1.hight=max(self.get_hight(k1.left), self.get_hight(k2))+1
return k1
def RR_SingleRotate(self,k2):
#update root return new root_node
k1=k2.right
k2.right=k1.left
k1.left=k2
k2.hight=max(self.get_hight(k2.right), self.get_hight(k2.left))+1
k1.hight=max(self.get_hight(k1.right), self.get_hight(k2))+1
return k1
def LR_DoubleRotate(self,k3):
k3.left=self.RR_SingleRotate(k3.left)
return self.LL_SingleRotate(k3)
def RL_DoubleRotate(self,k3):
k3.left=self.LL_SingleRotate(k3.right)
return self.RR_SingleRotate(k3)
def analyze(self,fun):
cProfile.run(fun)
#
# def avl_insert(self,avl_ins_node):
# root_path=[]
# self.insert(avl_ins_node)
# self.find(avl_ins_node.data, root_path)
# root_path.reverse()
#
# # isBalance function
# def isBalance(node_list):
# pass
#
# # root_path[i] is the unbalance node_list
# for i in range(0,len(root_path)):
# if False==isBalance(root_path[i]):
# break
# #return root_path[i]
# else:
# raise "ValueErrorError"
if __name__ == '__main__':
def insert_profile():
root=Node(0)
t=AVL_Trie(root)
i=1000
while i>0:
i-=1
ins_node=(Node(random.randint(0,100000)))
print(ins_node.data,end=",")
root=t.avl_insert(ins_node, root)
print("######## insert process #####")
print("\n")
cProfile.run("insert_profile()")