python实现平衡二叉树_Python实现自平衡二叉树AVL

# -*- coding: utf-8 -*-

from enum import Enum

#参考http://blog.csdn.net/niteip/article/details/11840691/

#参考https://www.cnblogs.com/suimeng/p/4560056.html

#todo 还没有考虑高度的增减,只考虑了平衡因子

#todo 加上非递归遍历二叉树

class BFStatus(Enum):

# 左子树的高度减去右子树的高度 RH,EH,LH分别表示右子树较高,左右子树等高,左子树较高

LH = 1

EH = 0

RH = -1

class TreeNode(object):

def __init__(self):

self.lson = None

self.rson = None

self.pnode = None

self.data = None

self.freq = 0

self.hgt = -1

self.bfstatus = BFStatus().EH

class AVLTree(object):

def __init__(self,root_node):

self.root = TreeNode

def height(self,node):

if node is not None:

return node.hgt

return -1

def max(self,campa,campb):

if campa > campb:

return campa

else:

return campb

def single_rotate_right(self, node): # 右单旋转 RR

parent_node = node.pnode

node1 = node.lson

node.lson = node1.rson

node1.rson = node

if parent_node.lson == node:

parent_node.lson = node1

else:

parent_node.rson = node1

node1.pnode = parent_node

node.pnode = node1

def single_rotate_left(self, node): # 左单旋转 LL

parent_node = node.pnode

node1 = node.rson

node.rson = node1.lson

node1.lson = node

if parent_node.lson == node:

parent_node.lson = node1

else:

parent_node.rson = node1

node1.pnode = parent_node

node.pnode = node1

def LeftBalance(self,node):

lchild = node.lson

BFStatus_code = BFStatus()

if lchild.bfstatus == BFStatus_code.EH:

node.bfstatus = lchild.bfstatus = BFStatus_code.LH

lchild.bfstatus = BFStatus.RH

self.single_rotate_right(node)

elif lchild.bfstatus == BFStatus_code.LH:#LL型

node.bfstatus = lchild.bfstatus = BFStatus.EH

self.single_rotate_right(node)

elif lchild.bfstatus == BFStatus.RH:#LR型

rchild = lchild.rson

if rchild.bfstatus == BFStatus.EH:

node.bfstatus = BFStatus.RH

lchild.bfstatus = BFStatus.EH

elif rchild.bfstatus == BFStatus.LH:

node.bfstatus = BFStatus.EH

lchild.bfstatus = BFStatus.LH

elif rchild.bfstatus == BFStatus.RH:

node.bfstatus = BFStatus.EH

lchild.bfstatus = BFStatus.EH

rchild.bfstatus = BFStatus.EH

self.single_rotate_left(lchild)

self.single_rotate_right(node)

def RightBalance(self,node):

rchild = node.rson

BFStatus_code = BFStatus()

if rchild.bfstatus == BFStatus_code.RH:

node.bfstatus = node.bfstatus = BFStatus_code.EH

self.single_rotate_left(node)

elif rchild.bfstatus == BFStatus_code.EH:#LL型

node.bfstatus = rchild.bfstatus = BFStatus.RH

rchild.bfstatus = BFStatus.LH

self.single_rotate_left(node)

elif rchild.bfstatus == BFStatus.LH:#LR型

lchild = rchild.lson

if lchild.bfstatus == BFStatus.LH:

node.bfstatus = BFStatus.EH

rchild.bfstatus = BFStatus.RH

elif lchild.bfstatus == BFStatus.RH:

node.bfstatus = BFStatus.LH

rchild.bfstatus = BFStatus.EH

elif lchild.bfstatus == BFStatus.EH:

node.bfstatus = BFStatus.EH

rchild.bfstatus = BFStatus.EH

lchild.bfstatus = BFStatus.EH

self.single_rotate_right(rchild)

self.single_rotate_left(node)

def insertpri(self,node,data,stack_list,taller_param=True):

if node == None:

node = TreeNode()

node.data = data

node.pnode = stack_list[-1]

else:

stack_list.append(node)

if node.data < data:

(sign,taller) = self.insertpri(node.lson,data,stack_list)

if sign == False:

return (False,taller_param)

if taller == True:

if node.bfstatus == BFStatus().LH:

self.LeftBalance(node)

taller_param = False

elif node.bfstatus == BFStatus().EH:

node.bfstatus = BFStatus().LH

taller_param = True

elif node.bfstatus == BFStatus().RH:

node.bfstatus = BFStatus().EH

taller_param = False

elif node.data > data:

stack_list.append(node)

if node.data < data:

(sign, taller) = self.insertpri(node.rson, data, stack_list)

if sign == False:

return (False, taller_param)

if taller == True:

if node.bfstatus == BFStatus().LH:

node.bfstatus = BFStatus().EH

taller_param = False

elif node.bfstatus == BFStatus().EH:

node.bfstatus = BFStatus().RH

taller_param = True

elif node.bfstatus == BFStatus().RH:

self.RightBalance(node)

taller_param = False

else:

node.freq += 1

return (True,taller_param)

def insert(self,data):

stack_list = []

self.insertpri(self.root,data,stack_list)

def searchpri(self,node,data):

if node is None:

return None

elif node.data > data:

self.searchpri(node.lson,data)

elif node.data < data:

self.searchpri(node.rson,data)

else:

return node

def search(self,data):

self.searchpri(self.root,data)

def go_far_left(self,node):

if node.lson is None:

return node

else:

self.go_far_left(node.lson)

def go_far_right(self,node):

if node.rson is None:

return node

else:

self.go_far_right(node.rson)

def delete_left(self,node,bfchild):

#当bf为-1或1变为0,或者孩子为空时说明子树高降低

if node.lson is None or (bfchild != BFStatus().EH and node.lson.bfstatus == BFStatus().EH):

#左子树树高降低

if node.bfstatus == BFStatus().EH:

node.bfstatus = BFStatus().RH

elif node.bfstatus == BFStatus().LH:

node.bfstatus = BFStatus().EH

elif node.bfstatus == BFStatus().RH:#原本右子树比较高

self.RightBalance(node)

def delete_right(self,node,bfchild):

#当bf为LH或RH变为EH,或者孩子为空时说明子树高降低

if node.rson is None or (bfchild != BFStatus().EH and node.rson.bfstatus == BFStatus().EH):

#左子树树高降低

if node.bfstatus == BFStatus().EH:

node.bfstatus = BFStatus().LH

elif node.bfstatus == BFStatus().RH:

node.bfstatus = BFStatus().EH

elif node.bfstatus == BFStatus().LH:#原本左子树比较高

self.LeftBalance(node)

def deletepri(self,node,data):

bfchild = BFStatus().EH

if node == None:

return None

if node.data > data:

bfchild = node.lson.bfstatus

node.lson = self.deletepri(node.lson,data)

self.delete_left(node,bfchild)

elif node.data < data:

bfchild = node.rson.bfstatus

node.rson = self.deletepri(node.rson, data)

self.delete_left(node, bfchild)

else:

if node.lson is not None: #不是叶子结点并且具有直接前驱

far_right_node = self.go_far_right(node.lson)#直接前驱

node.data = far_right_node.data

node.lson = self.deletepri(node.lson,far_right_node.data)#可以确定,删除的节点为当前节点的左子树的某一个节点

self.delete_left(node,bfchild)

elif node.rson is not None:

far_left_node = self.go_far_left(node.rson)

node.data = far_left_node.data

node.rson = self.deletepri(node.rson,far_left_node.data)

self.delete_right(node,bfchild)

else:#叶子结点

node = None

return node

def delete(self,data):

self.deletepri(self.root,data)

def insubtree(self,node):

if node is None:

return

self.insubtree(node.lson)

print(node.data)

self.insubtree(node.rson)

def traversal(self):

self.insubtree(self.root)

if __name__ == '__main__':

root_node = TreeNode()

tree_obj = AVLTree(root_node)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个简单的 Python 实现平衡二叉树 (AVL Tree) 的代码示例: ```python class Node: def __init__(self, key): self.key = key self.left = None self.right = None self.height = 1 class AVL_Tree: def insert(self, root, key): if not root: return Node(key) elif key < root.key: root.left = self.insert(root.left, key) else: root.right = self.insert(root.right, key) root.height = 1 + max(self.getHeight(root.left), self.getHeight(root.right)) balance = self.getBalance(root) if balance > 1 and key < root.left.key: return self.rightRotate(root) if balance < -1 and key > root.right.key: return self.leftRotate(root) if balance > 1 and key > root.left.key: root.left = self.leftRotate(root.left) return self.rightRotate(root) if balance < -1 and key < root.right.key: root.right = self.rightRotate(root.right) return self.leftRotate(root) return root def leftRotate(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def rightRotate(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self.getHeight(z.left), self.getHeight(z.right)) y.height = 1 + max(self.getHeight(y.left), self.getHeight(y.right)) return y def getHeight(self, root): if not root: return 0 return root.height def getBalance(self, root): if not root: return 0 return self.getHeight(root.left) - self.getHeight(root.right) ``` 这个代码实现AVL 树的基本操作,包括插入节点、左旋、右旋和平衡因子的计算。 使用的时候只需要实例化 AVL_Tree 类,并调 ### 回答2: 平衡二叉树AVL树)是一种自平衡的二叉搜索树,任何节点的左子树和右子树的高度最多相差1。下面是用Python实现平衡二叉树的代码: ```python # 定义二叉树节点类 class TreeNode: def __init__(self, value): self.data = value self.left = None self.right = None self.height = 1 # 节点的高度,默认为1 # 获取节点的高度 def get_height(node): if node is None: return 0 return node.height # 获取节点的平衡因子 def get_balance(node): if node is None: return 0 return get_height(node.left) - get_height(node.right) # 左旋操作 def left_rotate(z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = max(get_height(z.left), get_height(z.right)) + 1 y.height = max(get_height(y.left), get_height(y.right)) + 1 return y # 右旋操作 def right_rotate(z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = max(get_height(z.left), get_height(z.right)) + 1 y.height = max(get_height(y.left), get_height(y.right)) + 1 return y # 插入节点 def insert_node(root, value): if root is None: return TreeNode(value) elif value < root.data: root.left = insert_node(root.left, value) else: root.right = insert_node(root.right, value) root.height = max(get_height(root.left), get_height(root.right)) + 1 # 检测树的平衡性 balance_factor = get_balance(root) # 左左情况,进行右旋操作 if balance_factor > 1 and value < root.left.data: return right_rotate(root) # 右右情况,进行左旋操作 if balance_factor < -1 and value > root.right.data: return left_rotate(root) # 左右情况,先左旋再右旋 if balance_factor > 1 and value > root.left.data: root.left = left_rotate(root.left) return right_rotate(root) # 右左情况,先右旋再左旋 if balance_factor < -1 and value < root.right.data: root.right = right_rotate(root.right) return left_rotate(root) return root # 中序遍历,打印平衡二叉树 def in_order_traversal(root): if root: in_order_traversal(root.left) print(root.data, end=" ") in_order_traversal(root.right) # 测试代码 root = None root = insert_node(root, 10) root = insert_node(root, 20) root = insert_node(root, 30) root = insert_node(root, 40) root = insert_node(root, 50) root = insert_node(root, 25) print("平衡二叉树:") in_order_traversal(root) ``` 以上代码实现平衡二叉树的插入操作,并进行了相应的旋转操作来维持平衡。可以通过中序遍历验证平衡二叉树的正确性。 ### 回答3: 平衡二叉树AVL树)是一种特殊的二叉搜索树,它的左右子树的高度差不超过1。 实现平衡二叉树的代码,主要包含以下几个步骤: 1. 定义二叉树的节点类,包含节点值、左子节点、右子节点和高度等属性。 2. 定义平衡二叉树类,包含插入节点、删除节点、左旋转、右旋转、计算节点高度等方法。 3. 在插入节点、删除节点等操作中,通过判断节点的左子树和右子树的高度差,来判断是否需要进行旋转操作以保持树的平衡。 4. 左旋转和右旋转是平衡二叉树中常用的平衡操作,可以通过调整节点的左右子节点来保持树的平衡。 5. 计算节点的高度时,需要递归计算节点的左子树和右子树的高度,然后取较大值加1作为节点的高度。 6. 实现其他常用方法,如查找节点、遍历树等。 下面是一种可能的Python实现平衡二叉树的代码示例: ```python class TreeNode: def __init__(self, val): self.val = val self.left = None self.right = None self.height = 1 class AVLTree: def __init__(self): self.root = None def insert(self, root, val): if not root: return TreeNode(val) elif val < root.val: root.left = self.insert(root.left, val) else: root.right = self.insert(root.right, val) root.height = 1 + max(self.get_height(root.left), self.get_height(root.right)) balance = self.get_balance(root) if balance > 1 and val < root.left.val: return self.right_rotate(root) if balance < -1 and val > root.right.val: return self.left_rotate(root) if balance > 1 and val > root.left.val: root.left = self.left_rotate(root.left) return self.right_rotate(root) if balance < -1 and val < root.right.val: root.right = self.right_rotate(root.right) return self.left_rotate(root) return root def delete(self, root, val): if not root: return root elif val < root.val: root.left = self.delete(root.left, val) elif val > root.val: root.right = self.delete(root.right, val) else: if not root.left: temp = root.right root = None return temp elif not root.right: temp = root.left root = None return temp temp = self.get_min_value_node(root.right) root.val = temp.val root.right = self.delete(root.right, temp.val) root.height = 1 + max(self.get_height(root.left), self.get_height(root.right)) balance = self.get_balance(root) if balance > 1 and self.get_balance(root.left) >= 0: return self.right_rotate(root) if balance < -1 and self.get_balance(root.right) <= 0: return self.left_rotate(root) if balance > 1 and self.get_balance(root.left) < 0: root.left = self.left_rotate(root.left) return self.right_rotate(root) if balance < -1 and self.get_balance(root.right) > 0: root.right = self.right_rotate(root.right) return self.left_rotate(root) return root def left_rotate(self, z): y = z.right T2 = y.left y.left = z z.right = T2 z.height = 1 + max(self.get_height(z.left), self.get_height(z.right)) y.height = 1 + max(self.get_height(y.left), self.get_height(y.right)) return y def right_rotate(self, z): y = z.left T3 = y.right y.right = z z.left = T3 z.height = 1 + max(self.get_height(z.left), self.get_height(z.right)) y.height = 1 + max(self.get_height(y.left), self.get_height(y.right)) return y def get_height(self, root): if not root: return 0 return root.height def get_balance(self, root): if not root: return 0 return self.get_height(root.left) - self.get_height(root.right) def get_min_value_node(self, root): if root is None or root.left is None: return root return self.get_min_value_node(root.left) def search(self, root, val): if not root or root.val == val: return root elif root.val < val: return self.search(root.right, val) else: return self.search(root.left, val) def inorder_traversal(self, root): res = [] if root: res = self.inorder_traversal(root.left) res.append(root.val) res = res + self.inorder_traversal(root.right) return res ``` 注意,这只是一种可能的实现,实际的代码可能会有所不同。可以根据具体需求和算法原理进行调整。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值