日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

数据结构与算法笔记(十六)—— 二叉搜索树

發(fā)布時間:2025/3/21 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构与算法笔记(十六)—— 二叉搜索树 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一、二叉搜索樹定義

二叉搜索樹(Binary Search Tree),又名二叉排序樹(Binary Sort Tree)。

二叉搜索樹是具有有以下性質(zhì)的二叉樹:

  • 若左子樹不為空,則左子樹上所有節(jié)點的值均小于或等于它的根節(jié)點的值。
  • 若右子樹不為空,則右子樹上所有節(jié)點的值均大于或等于它的根節(jié)點的值。
  • 左、右子樹也分別為二叉搜索樹。

二、二叉搜索樹的操作

2.1、結(jié)點創(chuàng)建

class Node(object):"""節(jié)點類"""def __init__(self, elem=-1, lchild=None, rchild=None,parent=None):self.elem = elemself.lchild = lchildself.rchild = rchildself.parent = parent

2.2、樹的創(chuàng)建

class BTree(object):def __init__(self):self.root = Nonedef insert(self,node,val):'''為樹添加結(jié)點: 遞歸'''if self.root is None:self.root = Node(val)returnif node is None:node = Node(val)return nodeif val < node.elem:node.lchild = self.insert(node.lchild,val)node.lchild.parent = nodeelif val > node.elem:node.rchild = self.insert(node.rchild,val)node.rchild.parent = nodereturn nodedef insert_no_rec(self,val):'''為樹添加結(jié)點: 非遞歸'''p = self.rootif not p: #空樹self.root = Node(val)returnwhile True:if val < p.elem:if p.lchild:p = p.lchildelse: #左孩子不存在p.lchild = Node(val)p.lchild.parent = preturnelif val > p.elem:if p.rchild:p = p.rchildelse: #右孩子不存在p.rchild = Node(val)p.rchild.parent = preturnelse:return

2.3、遍歷

(即二叉樹遍歷,代碼參考我博客:數(shù)據(jù)結(jié)構(gòu)與算法筆記(十四)—— 二叉樹)


2.4、查找

def search(self,val):p = self.rootwhile p:if p.elem <val:p = p.rchildelif p.elem > val:p = p.rchildelse:return Truereturn False

測試:

print(tree.search(20)) #結(jié)果:False print(tree.search(13)) #結(jié)果:True

2.5、刪除

二叉查找樹的刪除操作分為三種情況:

① 要刪除的節(jié)點是葉子節(jié)點:直接刪除

代碼:

def delNode_1(self,node):'''情況1:node是葉子結(jié)點(即無左子樹又無右子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = Noneelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = Noneelse: #node是它父親的右孩子node.parent.rchild = None

② 要刪除的節(jié)點只有一個孩子:將此節(jié)點的父親與孩子連接,然后刪除該節(jié)點

代碼:

def delNode_21(self,node):'''情況2:node只有一個左孩子(只有左子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = node.lchildelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse: #node是它父親的右孩子node.parent.rchild = node.lchildnode.lchild.parent = node.parentdef delNode_22(self,node):'''情況2:node只有一個右孩子(只有右子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = node.rchildelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = node.rchildnode.rchild.parent = node.parentelse: #node是它父親的右孩子node.parent.rchild = node.rchildnode.rchild.parent = node.parent

③ 要刪節(jié)點既有左子樹也有右子樹:找到該節(jié)點右子樹中最小值節(jié)點,使用該節(jié)點代替待刪除節(jié)點,然后在右子樹中刪除最小值節(jié)點。

代碼:

def defNode_3(self,node):'''情況3:既有左孩子又有右孩子'''min_node = node.rchildwhile min_node.lchild:min_node = min_node.lchildnode.data = min_node.elem# 刪除min_nodeif min_node.rchild:self.delNode_22(min_node)else:self.delNode_1(min_node)

刪除結(jié)點完整代碼:

def delNode(self,val):'''刪除二叉搜索樹中值為val的點'''if not self.root:return False_,node = self.search(val)if not node:return Falseif not node.lchild and not node.rchild: #1.葉子結(jié)點self.delNode_1(node)elif not node.rchild: #2.1 只有一個左孩子self.delNode_21(node)elif not node.lchild: #2.3 只有一個右孩子self.delNode_22(node)else: #3.兩個孩子都有self.defNode_3(node)

測試:

tree.preorder(tree.root) #結(jié)果:13 14 94 33 25 82 59 65 tree.delNode(13) tree.preorder(tree.root) #結(jié)果:14 94 33 25 82 59 65

完整代碼

class Node(object):"""節(jié)點類"""def __init__(self, elem=-1, lchild=None, rchild=None,parent=None):self.elem = elemself.lchild = lchildself.rchild = rchildself.parent = parentclass BTree(object):def __init__(self):self.root = Nonedef insert(self,node,val):'''為樹添加結(jié)點: 遞歸'''if self.root is None:self.root = Node(val)returnif node is None:node = Node(val)return nodeif val < node.elem:node.lchild = self.insert(node.lchild,val)node.lchild.parent = nodeelif val > node.elem:node.rchild = self.insert(node.rchild,val)node.rchild.parent = nodereturn nodedef insert_no_rec(self,val):'''為樹添加結(jié)點: 非遞歸'''p = self.rootif not p: #空樹self.root = Node(val)returnwhile True:if val < p.elem:if p.lchild:p = p.lchildelse: #左孩子不存在p.lchild = Node(val)p.lchild.parent = preturnelif val > p.elem:if p.rchild:p = p.rchildelse: #右孩子不存在p.rchild = Node(val)p.rchild.parent = preturnelse:returndef search(self,val):p = self.rootwhile p:if p.elem <val:p = p.rchildelif p.elem > val:p = p.rchildelse:return True,preturn Falsedef preorder(self,node):'''先序遍歷'''if node is None:returnprint(node.elem, end=' ')self.preorder(node.lchild)self.preorder(node.rchild)def delNode_1(self,node):'''情況1:node是葉子結(jié)點(即無左子樹又無右子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = Noneelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = Noneelse: #node是它父親的右孩子node.parent.rchild = Nonedef delNode_21(self,node):'''情況2:node只有一個左孩子(只有左子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = node.lchildelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = node.lchildnode.lchild.parent = node.parentelse: #node是它父親的右孩子node.parent.rchild = node.lchildnode.lchild.parent = node.parentdef delNode_22(self,node):'''情況2:node只有一個右孩子(只有右子樹)'''if not node.parent: #沒有父節(jié)點說明是根節(jié)點self.root = node.rchildelif node == node.parent.lchild: #node是它父親的左孩子node.parent.lchild = node.rchildnode.rchild.parent = node.parentelse: #node是它父親的右孩子node.parent.rchild = node.rchildnode.rchild.parent = node.parentdef defNode_3(self,node):'''情況3:既有左孩子又有右孩子'''min_node = node.rchildwhile min_node.lchild:min_node = min_node.elemnode.data = min_node.elem# 刪除min_nodeif min_node.rchild:self.delNode_22(min_node)else:self.delNode_1(min_node)def delNode(self,val):'''刪除二叉搜索樹中值為val的點'''if not self.root:return False_,node = self.search(val)if not node:return Falseif not node.lchild and not node.rchild: #1.葉子結(jié)點self.delNode_1(node)elif not node.rchild: #2.1 只有一個左孩子self.delNode_21(node)elif not node.lchild: #2.3 只有一個右孩子self.delNode_22(node)else: #3.兩個孩子都有self.defNode_3(node)if __name__ == '__main__':li = [13,14,94,33,82,25,59,94,65]tree = BTree() #=========添加結(jié)點============= for i in li:tree.insert(tree.root,i)tree.preorder(tree.root)print('') #=========查找元素============= # print(tree.search(14)) #=========刪除結(jié)點============= tree.delNode(13)print('')tree.preorder(tree.root)

總結(jié)

以上是生活随笔為你收集整理的数据结构与算法笔记(十六)—— 二叉搜索树的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。