代码仅供参考!
#coding:utf-8
import scrapy
import xlwt, lxml
import re, json
import matplotlib.pyplot as plt
import numpy as np
import pylab
from scipy import linalg
import sys
#树
#二叉查找树
'''
给定一颗二叉查找树,查找某节点p的过程就是递归过程
若当前节点cur的值小于p的值,查找cur的左子树
若当前节点cur的值不小于p的值,查找cur的右子树
递归上述过程,直到cur==p或者cur为空
'''
class Node:
def __init__(self,data):
self.data=data
self.lchild=None
self.rchild=None
self.height=None
self.freq=None
def search(self,node,data):
if node is None:
return False,node
if node.data==data:
return True,node
if datanode.data:
node.rchild=self.insert(node.rchild,data)
else:
node.lchild=self.insert(node.lchild,data)
return node
#删除
#记待删除节点为p,分三种情况进行处理:
# p为叶子节点:直接删除该节点,再修改p的父节点的指针
# p为单支节点:将p的子树与p的父亲节点相连,删除p即可
# p的左子树和右子树均不空:找到p的直接后继d(p的右孩子的最左子孙【确保找到的是大于待删除节点的最小值,即确保依然是二叉查找树】);因d一定没有左子树,所以使用删除单支节点的方法:删除d,并让d的父亲节点dp称为d的右子树的父亲节点;同时,用d的值替换p的值
# 相对的,可以找p的直接前驱x(p的左孩子的最右子孙),x一定没有右子树,所以可删除x,并让x的父亲节点成为x的左子树的父亲节点
def delete(self,node,data):
flag,n=self.search(node,data)
if not flag:
print('无该关键字,删除失败')
else:
if n.lchild and n.rchild:#左右子树均有[找直接后继]
temp=n.rchild
while temp.lchild:
temp=temp.lchild
n.data=temp.data
del temp
else:
temp = n
if n.lchild is None: # 没有左子树
n = n.rchild
del temp
elif n.rchild is None: # 没有右子树
n = n.lchild
del temp
return
#二叉树的遍历
#前序/中序/后序遍历
#前序遍历:根、左、右
def preOrder(self,node):
if node is not None:
print(node.data)
self.preOrder(node.lchild)
self.preOrder(node.rchild)
#中序遍历:左、根、右【数组的升序】
def inOrder(self,node):
if node is not None:
self.inOrder(node.lchild)
print(node.data)
self.inOrder(node.rchild)
#后序遍历:左、右、根
def postOrder(self,node):
if node is not None:
self.postOrder(node.lchild)
self.postOrder(node.rchild)
print(node.data)
#根据前序中序,计算后序
#如:已知某二叉树的遍历结果如下,求它的后序遍历
# pre:GDAFEMHZ
# mid:ADEFGHMZ
#两个步骤:
# 1.根据前序中序构造二叉树
# 2.后序遍历二叉树
def inPre2Post(self,inOrder,preOrder,a):
if len(preOrder)==0:
return
node=preOrder[0]
nroot=inOrder.index(node)#找到前序遍历的节点在中序遍历的位置
# nroot=0
# for nroot in range(0,length):
# if(inOrder[nroot]==node):
# break
#
self.inPre2Post(inOrder,preOrder[1:nroot+1],a)#左孩子部分
self.inPre2Post(inOrder[nroot+1:],preOrder[nroot+1:],a)#右孩子部分
# print(node)
a.append(node)
print(a)
return a
#已知中序后序,求前序遍历,同理
# node=Node('G')
# inOrder=['A','D','E','F','G','H','M','Z']
# preOrder=['G','D','A','F','E','M','H','Z']
#
# node.inPre2Post(inOrder,preOrder,[])
#平衡二叉树
# 高度不平衡:单旋转:左左,右右| 右左,左右:双旋转
'''
k2为根节点,k1左孩子节点
左左,左子树节点k1向上旋转为根节点,k1的右孩子变换为k2左孩子
'''
def height(self,node):#递归求深度
if node==None:
return 0
else:
lh=self.height(node.lchild)
rh=self.height(node.rchild)
node.height=max(lh,rh)+1
return node.height
def singleRotateLeft(self,k2):#左左
k1=k2.lchild
k2.lchild=k1.rchild
k1.rchild=k2
k2.height=max(self.height(k2.lchild),self.height(k2.rchild))+1
k1.height=max(self.height(k1.lchild),k2.height)+1
return k1
def singleRotateRight(self, k2):#右右
k1 = k2.rchild
k2.rchild = k1.lchild
k1.lchild = k2
k2.height = max(self.height(k2.lchild), self.height(k2.rchild)) + 1
k1.height = max(self.height(k1.rchild), k2.height) + 1
return k1
#左右:k3为根节点,它的左子树k1比右子树D深2层,且k1子树更深的是其右子树k2
def rotateLR(self,k3):#画图更加明了
self.singleRotateRight(k3.lchild)
self.singleRotateLeft(k3)
#右左;
def rotateRL(self,k3):
self.singleRotateLeft(k3.rchild)
self.singleRotateRight(k3)
'''
#平衡二叉树的插入:
插入方法和二叉查找树基本一样,区别是,插入完成后需要从插入的节点开始维护一个到根节点的路径【递归压入栈的过程】,每经过一个节点都要维持树的平衡。维持树的平衡需要根据高度差的特点选择不同的旋转算法
'''
def insertOfAVL(self,node,data):
if node is None:#节点为空,则在此节点插入data
node=Node(data)
return node
if data>node.data:#如果小于当前节点值,则遍历当前节点的左子树插入data
self.insertOfAVL(node.rchild,data)
if(2==self.height(node.rchild)-self.height(node.lchild)):#高度差=2则不平衡,且前提已是右不平衡
if data>node.rchild.data:#右右
self.singleRotateRight(node)
else:
self.rotateRL(node)
elif dataself.height(node.rchild.rchild)):
self.rotateRL(node)
else:
self.singleRotateRight(node)
elif data>node.data:
self.deleteOfAVL(node.rchild,data)
if 2==self.height(node.lchild)-self.height(node.rchild):
if node.lchild.rchild is not None and (self.height(node.lchild.rchild)>self.height(node.lchild.lchild)):
self.rotateLR(node)
else:
self.singleRotateLeft(node)
else:
if node.lchild and node.rchild:
temp = node.rchild
#找到其直接后继
while temp.lchild:
temp=temp.lchild
node.data =temp.data
node.freq=temp.freq
# pre.lchild = next.rchild
self.deleteOfAVL(node.rchild,temp.data) #???????????
del temp
if 2==self.height(node.lchild)-self.height(node.rchild):
if node.lchild.rchild is not None and (
self.height(node.lchild.rchild) > self.height(node.lchild.lchild)):
self.rotateLR(node)
else:
self.singleRotateLeft(node)
else:
temp=node
if node.lchild is None:
node=node.rchild
elif node.rchild is None:
node=node.lchild
del temp
node.height=max(self.height(node.lchild),self.height(node.rchild))+1