【數據結構】二叉排序樹

?

二叉排序樹(Binary Sort Tree)又稱二叉查找樹(Binary Search Tree),亦稱二叉搜索樹。

特點

?

二叉排序樹或者是一棵空樹,或者是具有下列性質的二叉樹:

?

1、若左子樹不空,則左子樹上所有結點的值均小于它的根結點的值;

2、若右子樹不空,則右子樹上所有結點的值均大于它的根結點的值;

3、左、右子樹也分別為二叉排序樹;

4、沒有鍵值相等的節點。

?

特性

?

二叉排序樹通常采用二叉鏈表作為存儲結構。中序遍歷二叉排序樹可得到一個依據關鍵字的有序序列,一個無序序列可以通過構造一棵二叉排序樹變成一個有序序列,構造樹的過程即是對無序序列進行排序的過程。每次插入的新的結點都是二叉排序樹上新的葉子結點,在進行插入操作時,不必移動其它結點,只需改動某個結點的指針,由空變為非空即可。搜索、插入、刪除的時間復雜度等于樹高,期望O(logn),最壞O(n)(數列有序,樹退化成線性表,如右斜樹)。

?

查找算法

?

步驟:

1、若子樹為空,查找不成功。

2、二叉樹若根結點的關鍵字值等于查找的關鍵字,成功。

3、否則,若小于根結點的關鍵字值,遞歸查左子樹。

4、若大于根結點的關鍵字值,遞歸查右子樹。

?

插入算法

?

步驟:

1、執行查找算法,找出被插結點的父親結點。

2、判斷被插結點是其父親結點的左、右兒子。將被插結點作為葉子結點插入。

3、若二叉樹為空。則首先單獨生成根結點。

?

刪除算法

?

步驟:

1.若*p結點為葉子結點,即PL(左子樹)和PR(右子樹)均為空樹。由于刪去葉子結點不破壞整棵樹的結構,則只需修改其雙親結點的指針即可。

?

?2.若*p結點只有左子樹PL或右子樹PR,此時只要令PL或PR直接成為其雙親結點*f的左子樹(當*p是左子樹)或右子樹(當*p是右子樹)即可,作此修改也不破壞二叉排序樹的特性。

?

?3.若*p結點的左子樹和右子樹均不空。在刪去*p之后,為保持其它元素之間的相對位置不變,可按中序遍歷保持有序進行調整。比較好的做法是,找到*p的直接前驅(或直接后繼)*s,用*s來替換結點*p,然后再刪除結點*s。

?

二叉排序樹的實現練習(Java

?

public class BinarySortTree {private TreeNode root=null;/*** 獲取樹的高度* @param subTree * @return*/private int height(TreeNode subTree){if(subTree == null){return 0;}else{int i = height(subTree.leftChild);int j = height(subTree.rightChild);return (i>j)?(i+1):(j+1);}}/*** 獲取樹的節點數* @param subTree* @return*/private int size(TreeNode subTree){if(subTree == null){return 0;}else{return size(subTree.leftChild)+size(subTree.rightChild)+1;}}/*** 前序遍歷  * @param subTree*/public void preOrder(TreeNode subTree){  if(subTree!=null){visted(subTree);  preOrder(subTree.leftChild); preOrder(subTree.rightChild); }}  /*** 中序遍歷  * @param subTree*/public void inOrder(TreeNode subTree){  if(subTree!=null){  inOrder(subTree.leftChild);  visted(subTree);  inOrder(subTree.rightChild);  }  }  /*** 后續遍歷  * @param subTree*/public void postOrder(TreeNode subTree) {  if (subTree != null) {  postOrder(subTree.leftChild);  postOrder(subTree.rightChild);  visted(subTree);  }  }public void visted(TreeNode subTree){  System.out.print(subTree.data+",");}/*** 插入* @param subTree* @param iv*/public void insertNote(TreeNode subTree, int iv){TreeNode newNode = new TreeNode(iv);if(subTree == null){this.root = newNode;}else if(subTree.data > iv){if(subTree.leftChild == null){subTree.leftChild = newNode;newNode.parent = subTree;}else{insertNote(subTree.leftChild, iv);}}else if(subTree.data < iv){if(subTree.rightChild == null){subTree.rightChild = newNode;newNode.parent = subTree;}else{insertNote(subTree.rightChild, iv);}}else{System.out.println("node has exist.");}}/*** 查詢* @param subTree* @param fv* @return*/public boolean findNote(TreeNode subTree, int fv){if(subTree == null){return false;}else if(subTree.data > fv){return findNote(subTree.leftChild, fv);}else if(subTree.data < fv){return findNote(subTree.rightChild, fv);}else{return true;}}/*** 刪除節點* @param subTree* @param iv*/public void deleteNote(TreeNode subTree, int dv){if(subTree == null){System.out.println("BST is empty.");}else if(subTree.data > dv){deleteNote(subTree.leftChild, dv);}else if(subTree.data < dv){deleteNote(subTree.rightChild, dv);}else{if(subTree.leftChild == null && subTree.rightChild == null){/*如果左右子樹為空,怎直接刪除該節點*/if(subTree.parent == null){this.root = null;}else if(subTree.parent.leftChild == subTree){subTree.parent.leftChild = null;subTree.parent = null;}else if(subTree.parent.rightChild == subTree){subTree.parent.rightChild = null;subTree.parent = null;}}else if(subTree.leftChild != null && subTree.rightChild == null){/*如果左子樹不為空而右子樹為空,則直接用左子樹根節點替換刪除節點*/if(subTree.parent == null){this.root = subTree.leftChild;}else if(subTree.parent.leftChild == subTree){subTree.parent.leftChild = subTree.leftChild;}else if(subTree.parent.rightChild == subTree){subTree.parent.rightChild = subTree.leftChild;}subTree.leftChild.parent = subTree.parent;subTree.parent = null;subTree.leftChild = null;subTree = null;}else if(subTree.leftChild == null && subTree.rightChild != null){/*如果左子樹為空而右子樹不為空,則直接用右子樹根節點替換刪除節點*/if(subTree.parent == null){this.root = subTree.leftChild;}else if(subTree.parent.leftChild == subTree){subTree.parent.leftChild = subTree.rightChild;}else if(subTree.parent.rightChild == subTree){subTree.parent.rightChild = subTree.rightChild;}subTree.rightChild.parent = subTree.parent;subTree.parent = null;subTree.rightChild = null;subTree = null;}else{/*左右子樹都不為空的情況下,直接找前驅替代P,并釋放*/TreeNode p = subTree.leftChild;if(p.rightChild == null){/*P是刪除節點的左子樹最大值,即前驅,替換刪除節點*/if(subTree.parent == null){this.root = p;}else if(subTree.parent.leftChild == subTree){subTree.parent.leftChild = p;}else if(subTree.parent.rightChild == subTree){subTree.parent.rightChild = p;}p.parent = subTree.parent;p.rightChild = subTree.rightChild;subTree.rightChild.parent = p;}else{while(p.rightChild != null){p = p.rightChild;}if(p.leftChild != null){p.parent.rightChild = p.leftChild;p.leftChild.parent = p.parent;p.parent = null;p.leftChild = null;}else{p.parent.rightChild = null;p.parent = null;}/*P是刪除節點的左子樹最大值(即前驅),替換刪除節點*/if(subTree.parent == null){this.root = p;}else if(subTree.parent.leftChild == subTree){subTree.parent.leftChild = p;}else if(subTree.parent.rightChild == subTree){subTree.parent.rightChild = p;}p.parent = subTree.parent;p.leftChild = subTree.leftChild;subTree.leftChild.parent = p;p.rightChild = subTree.rightChild;subTree.rightChild.parent = p;}subTree.parent = null;subTree.leftChild = null;subTree.rightChild = null;subTree = null;}}}/** * 二叉樹的節點數據結構 */  private class  TreeNode{private int data;private TreeNode parent = null;private TreeNode leftChild=null;private TreeNode rightChild=null;public TreeNode(int data){  this.data=data; }  }public static void main(String[] args) {int[] tns = {1,3,4,6,7,8,10,13,14};for(int dv:tns){BinarySortTree bst = createBST();System.out.println("===============delete "+dv+" demo=====================");System.out.println("findNote("+dv+"):"+bst.findNote(bst.root, dv));    System.out.println("before delete inOrder:");bst.inOrder(bst.root);System.out.println("");bst.deleteNote(bst.root, dv);System.out.println("after delete inOrder:");bst.inOrder(bst.root);System.out.println("");System.out.println("");}}public static BinarySortTree createBST(){BinarySortTree bst = new BinarySortTree();bst.insertNote(bst.root, 8);bst.insertNote(bst.root, 3);bst.insertNote(bst.root, 10);bst.insertNote(bst.root, 1);bst.insertNote(bst.root, 6);bst.insertNote(bst.root, 14);bst.insertNote(bst.root, 4);bst.insertNote(bst.root, 7);bst.insertNote(bst.root, 13);return bst;}}

?

?

?

運行結果:

===============delete 1 demo=====================

findNote(1):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

3,4,6,7,8,10,13,14,

?

===============delete 3 demo=====================

findNote(3):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,4,6,7,8,10,13,14,

?

===============delete 4 demo=====================

findNote(4):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,6,7,8,10,13,14,

?

===============delete 6 demo=====================

findNote(6):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,7,8,10,13,14,

?

===============delete 7 demo=====================

findNote(7):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,6,8,10,13,14,

?

===============delete 8 demo=====================

findNote(8):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,6,7,10,13,14,

?

===============delete 10 demo=====================

findNote(10):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,6,7,8,13,14,

?

===============delete 13 demo=====================

findNote(13):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,6,7,8,10,14,

?

===============delete 14 demo=====================

findNote(14):true

before delete inOrder:

1,3,4,6,7,8,10,13,14,

after delete inOrder:

1,3,4,6,7,8,10,13,

轉載于:https://www.cnblogs.com/wcd144140/p/5465565.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/284845.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/284845.shtml
英文地址,請注明出處:http://en.pswp.cn/news/284845.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

記一次 .NET 某電廠Web系統 內存泄漏分析

一&#xff1a;背景 1. 講故事前段時間有位朋友找到我&#xff0c;說他的程序內存占用比較大&#xff0c;尋求如何解決&#xff0c;截圖就不發了&#xff0c;分析下來我感覺除了程序本身的問題之外&#xff0c;.NET5 在內存管理方面做的也不夠好&#xff0c;所以有必要給大家分…

Bomb(hdu 3555)

題意&#xff1a;給定一個閉區間&#xff0c;求區間內有多少數中含“49” /*dp[i][j]表示i位數以j為最高位位中的所有不符合數的個數。然后把數字拆分&#xff0c;亂搞即可。 */ #include<cstdio> #include<iostream> #define lon long long using namespace std; …

《深入實踐Spring Boot》下載

本書以豐富的實例&#xff0c;介紹了如何使用SpringBoot開發框架進行基礎應用和分布式應用等方面的開發&#xff0c;以及如何使用SpringBoot開發的應用構建高性能的服務平臺&#xff0c;同時還對SpringBoot的一些核心代碼進行了深入剖析。本書從基本的入門&#xff0c;到數據庫…

【ArcGIS微課1000例】0021:ArcToolBox工具箱功能與環境概述

文章目錄 一、ArcToolBox功能簡介1. 3D分析工具2. 分析工具3. 制圖工具4. 轉換工具5. 數據管理工具6. 地理編碼工具7. 地統計分析工具8. 線性參考工具9. 空間分析工具10. 空間統計工具二、ArcToolBox環境設置一、ArcToolBox功能簡介 ArcToolbox的空間處理工具條目眾多、功能豐…

[轉]將圖片轉換為 latex 公式

一、官網鏈接及使用方法 官網鏈接&#xff08;跨平臺&#xff09;: Mathpix 公式截圖快捷鍵截圖生成 latex 公式--------------------- 作者&#xff1a;man_world 來源&#xff1a;CSDN 原文&#xff1a;https://blog.csdn.net/mzpmzk/article/details/84140617 版權聲明&…

在SQL Server2005中使用 .NET程序集

昨天完成了一個最簡單的在數據庫中創建標量值函數,今天主要完成表值函數,存儲過程和用戶定義類型在和.NET結合下的使用方法.1,表值函數所謂表值函數就是說這個函數返回的結果是一個Table,而不是單個的值.在.NET 中創建這樣的函數,返回的結果是一個IEnumerable接口.這個接口非常…

C# 實例解釋面向對象編程中的接口隔離原則

在面向對象編程中&#xff0c;SOLID 是五個設計原則的首字母縮寫&#xff0c;旨在使軟件設計更易于理解、靈活和可維護。這些原則是由美國軟件工程師和講師羅伯特C馬丁(Robert Cecil Martin)提出的許多原則的子集&#xff0c;在他2000年的論文《設計原則與設計模式》中首次提出…

Appium同時運行多個設備

為了提高測試效率&#xff0c;測試需要同時在多個android設備上運行&#xff0c;就需要啟動多個appium。 啟動appium時&#xff0c;為每個設備設置不同的端口號&#xff0c;并為driver設置該設備的udid。見如下實例&#xff0c;關鍵是紅色部分 DesiredCapabilities capabilitie…

AI作畫的業界天花板被我找到了,AIGC模型揭秘 | 昆侖萬維

一、前景 1、AI和AIGC的關系 人工智能&#xff08;Artificial Intelligence&#xff09;&#xff0c;英文縮寫為AI。它是研究、開發用于模擬、延伸和擴展人的智能的理論、方法、技術及應用系統的一門新的技術科學。 AIGC是繼 UGC、PGC 之后新型利用AI技術自動生成內容的生產…

【ArcGIS微課1000例】0022:ArcGIS點(點坐標)自動連成線操作案例教程

ArcGIS中,可以將帶三維坐標(X、Y、Z)的點/點集自動連成線,本文演示具體操作流程。 文章目錄 實戰演練GPS點數據下載實戰演練 打開ArcMap軟件,添加實驗文件夾0022下的GPS軌跡點.shp矢量點數據(文末提供下載地址),該數據是由GPS RTK采集的河道點數據,首先需要將GPS點坐…

微信公眾號 文章的爬蟲系統

差不多倆個星期了吧&#xff0c;一直在調試關于微信公眾號的文章爬蟲系統&#xff0c;終于一切都好了&#xff0c;但是在這期間碰到了很多問題&#xff0c;今天就來回顧一下&#xff0c;總結一下&#xff0c;希望有用到的小伙伴可以學習學習。 1、做了倆次爬蟲了&#xff0c;第…

[轉]關于C#操作WPS和office兼容性的問題

最近一直在做的開發是關于導出word的功能&#xff0c;一開始的做法是在VS中直接添加引用office PIA&#xff0c;Microsoft.Office.Interop.Word&#xff0c;VS08有兩個版本&#xff0c;V11和V12&#xff0c;V11對應的是office03&#xff0c;V12對應的office07&#xff0c;試驗之…

AI入門到進階到放棄

前些天&#xff0c;發現了一個比較好的AI學習網站&#xff0c;有很多數學基礎&#xff0c;也通俗易懂&#xff0c;我自己先記錄起來防止忘記&#xff0c;猛戳這里&#xff08;學習網站&#xff09;

OAuth認證與授權

什么是OAuth授權&#xff1f; 一、什么是OAuth協議OAuth(開放授權)是一個開放標準。允許第三方網站在用戶授權的前提下訪問在用戶在服務商那里存儲的各種信息。而這種授權無需將用戶提供用戶名和密碼提供給該第三方網站。OAuth允許用戶提供一個令牌給第三方網站&#xff0c;一個…

IO的多路復用

一、概念: 使單線程或者單進程同時監測若干個文件描述符具有執行的能力&#xff1b; 二、作用: 類似于多進程和多線程 三、必要性: 多線程或者多進程對資源需求較高 四、IO模型: 1.阻塞io 不設置的話系統默認 2.非阻塞io 在阻塞io的基礎上調整為不在阻塞狀態 用到的函數接口…

C# 禁用 全局快捷鍵

本文經原作者授權以原創方式二次分享&#xff0c;歡迎轉載、分享。原文作者&#xff1a;唐宋元明清原文地址&#xff1a;https://www.cnblogs.com/kybs0/p/12558056.htmlC# 禁用 全局快捷鍵給軟件添加快捷鍵時&#xff0c;經常遇到其它軟件或者系統已設置的快捷鍵&#xff0c;導…

SegmentFault Hackathon 文藝復興

我有一個 idea&#xff0c;我想實現它&#xff0c;我正實現它&#xff0c;我已實現它。世界上存在一些好奇心旺盛、不愛墨守成規的人&#xff0c;略微偏執但又極度投入的他們崇尚自由&#xff0c;熱衷用技術實現自己的想法&#xff0c;他們帶著不羈的態度生活&#xff0c;利用編…

臥槽!VS Code 上竟然也能畫流程圖了???

作為一款開源的主流代碼編輯器&#xff0c;VSCode 在發布之后一直受到不少開發者的喜愛。 此前&#xff0c;我們也曾在公眾號上分享過多篇文章&#xff0c;向大家推薦了不少 VSCode 上比較實用&#xff08;或沙雕&#xff09;的插件。因此&#xff0c;有很多水友也經常調侃道&…

【QGIS入門實戰精品教程】14.1:QGIS如何加載各種在線地圖?

文章目錄 一、XYZ Tiles連接方式二、插件添加三、WMS/WMTS/OWS連接方式一、XYZ Tiles連接方式 1. 加載OpenStreetMap QGIS默認可以加載OpenStreetMap地圖。在左側點擊XYZ Tiles,默認下面有個OpenStreetMap選項,雙擊打右側會顯示地圖,如下圖所示: 在OpenStreetMap上右鍵→…

Oracle11g不能導出空表問題

ORACLE 11g 用exp命令導出庫文件備份時&#xff0c;發現只能導出來一部分表而且不提示錯誤&#xff0c;之前找不到解決方案只能把沒導出來的表重新建建立。后來發現是所有的空表都沒有導出來。于是想好好查查,因為在以前的10g版本中沒有這樣的問題。查資料發現Oracle 11g中有個…