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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

数据结构Java05【二叉树概述、二叉树遍历、堆排序、线索二叉树实现及遍历】

發布時間:2024/9/30 java 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 数据结构Java05【二叉树概述、二叉树遍历、堆排序、线索二叉树实现及遍历】 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

學習地址:【數據結構與算法基礎-java版】? ? ? ? ? ? ? ? ??🚀數據結構--Java專欄🚀

  • 筆記01【01-09】【概述、數組基本使用】【源碼、課件】
  • 筆記02【10-18】【棧、隊列、單鏈表(增刪節點)、循環鏈表、雙向循環鏈表、遞歸(斐波那契、漢諾塔)】
  • 筆記03【19-27】【(時間、空間復雜度);八大排序(冒泡、快速、插入、希爾、選擇、歸并、基數、隊列基數)】
  • 筆記04【28-33】【樹結構(二叉樹)概述、創建、遍歷、查找節點、刪除節點】
  • 筆記05【34-39】【順序存儲二叉樹概述、二叉樹遍歷、堆排序、線索二叉樹實現及遍歷】
  • 筆記06【40-48】【赫夫曼樹、概述、原理分析、代碼實現(數據壓縮、創建編碼表、解碼、壓縮文件、解壓文件)】
  • 筆記07【49-54】【二叉排序樹(添加、查找、刪除節點)】
  • 筆記08【55-57】【二叉平衡樹(AVL)-概述、單旋轉、雙旋轉】
  • 筆記09【58-60】【計算機中數據的存儲原理、2-3樹的插入原理、B樹和B+樹】
  • 筆記10【61-63】【哈希表概述、散列函數的設計、散列沖突解決方案】
  • 筆記11【64-67】【圖結構概述、圖遍歷原理(BFS\DFS)、圖遍歷代碼實現】

目? ?錄

P34-4.7順序存儲的二叉樹的概述

P35-4.8順序存儲的二叉樹的遍歷

P36-4.9常用排序算法之堆排序

P37-4.10線索二叉樹的概述

P38-4.11線索二叉樹代碼實現

1、TestThreadedBinaryTree.java

2、ThreadedBinaryTree.java

3、ThreadedNode.java

P39-4.12線索二叉樹的遍歷


P34-4.7順序存儲的二叉樹的概述

二叉樹數組的轉換

順序存儲的二叉樹通常情況,只考慮完全二叉樹

第n個元素的左子節點是:2*n+1;
第n個元素的右子節點是:2*n+2;
第n個元素的父節點是:(n-1)/2;

P35-4.8順序存儲的二叉樹的遍歷

將 數組 看成 完全二叉樹!以數組的方式遍歷二叉樹!

?

因為 根節點的左子節點 也會有 左子節點,所以需要遞歸。

P36-4.9常用排序算法之堆排序

大頂堆:父節點永遠大于子節點!數值大的 在?上面!

大頂堆 是 從大到小,小頂堆 是 從小到大!

升序排序 使用 大頂堆;降序排序 使用 小頂堆。

package demo4;import java.util.Arrays;public class HeapSort {public static void main(String[] args) {int[] arr = new int[] { 9, 6, 8, 7, 0, 1, 10, 4, 2 };heapSort(arr);System.out.println(Arrays.toString(arr));}public static void heapSort(int[] arr) {// 開始位置是最后一個非葉子節點,即最后一個節點的父節點int start = (arr.length - 1) / 2;// 調整為大頂堆for (int i = start; i >= 0; i--) {maxHeap(arr, arr.length, i);}// 先把數組中的第0個和堆中的最后一個數交換位置,再把前面的處理為大頂堆for (int i = arr.length - 1; i > 0; i--) {int temp = arr[0];arr[0] = arr[i];arr[i] = temp;maxHeap(arr, i, 0);}}public static void maxHeap(int[] arr, int size, int index) {// 左子節點int leftNode = 2 * index + 1;// 右子節點int rightNode = 2 * index + 2;int max = index;// 和兩個子節點分別對比,找出最大的節點if (leftNode < size && arr[leftNode] > arr[max]) {max = leftNode;}if (rightNode < size && arr[rightNode] > arr[max]) {max = rightNode;}// 交換位置if (max != index) {int temp = arr[index];arr[index] = arr[max];arr[max] = temp;// 交換位置以后,可能會破壞之前排好的堆,所以,之前的排好的堆需要重新調整maxHeap(arr, size, max);}}}

P37-4.10線索二叉樹的概述

左右指針,如果沒有存東西,則 可以 將 該節點的指針 指向 該節點的前一個節點 或 后一個節點。

找一個標記 區分 左(右子樹)、前(后節點)。

線索化二叉樹時,一個節點的一個節點,叫前驅節點;
線索化二叉樹時,一個節點的一個節點,叫后繼節點。

P38-4.11線索二叉樹代碼實現

1、TestThreadedBinaryTree.java

package demo7;public class TestThreadedBinaryTree {public static void main(String[] args) {// 創建一顆樹ThreadedBinaryTree binTree = new ThreadedBinaryTree();// 創建一個根節點ThreadedNode root = new ThreadedNode(1);// 把根節點賦給樹binTree.setRoot(root);// 創建一個左節點ThreadedNode rootL = new ThreadedNode(2);// 把新創建的節點設置為根節點的子節點root.setLeftNode(rootL);// 創建一個右節點ThreadedNode rootR = new ThreadedNode(3);// 把新創建的節點設置為根節點的子節點root.setRightNode(rootR);// 為第二層的左節點創建兩個子節點rootL.setLeftNode(new ThreadedNode(4));ThreadedNode fiveNode = new ThreadedNode(5);rootL.setRightNode(fiveNode);// 為第二層的右節點創建兩個子節點rootR.setLeftNode(new ThreadedNode(6));rootR.setRightNode(new ThreadedNode(7));// 中序遍歷樹binTree.midShow();System.out.println("\n===============");// 中序線索化二叉樹binTree.threadNodes();ThreadedNode afterFive = fiveNode.rightNode;System.out.println(afterFive.value);}}

2、ThreadedBinaryTree.java

package demo7;public class ThreadedBinaryTree {ThreadedNode root;// 用于臨時存儲前驅節點// 每次調用threadNodes()函數-臨時節點都會改變ThreadedNode pre = null;// 遍歷線索二叉樹public void threadIterate() {// 用于臨時存儲當前遍歷節點ThreadedNode node = root;while (node != null) {// 循環找到最開始的節點while (node.leftType == 0) {node = node.leftNode;}// 打印當前節點的值System.out.println(node.value);// 如果當前節點的右指針指向的是后繼節點,// 可能后繼節點還有后繼節點、while (node.rightType == 1) {node = node.rightNode;System.out.println(node.value);}// 替換遍歷的節點node = node.rightNode;}}// 設置根節點public void setRoot(ThreadedNode root) {this.root = root;}// 中序線索化二叉樹-遞歸遍歷-節點public void threadNodes() {threadNodes(root);}// 中序線索化二叉樹-遞歸遍歷-根據root節點不斷遞歸public void threadNodes(ThreadedNode node) {// 當前節點如果為null,直接返回if (node == null) {return;}// 處理左子樹---左子樹為空,指針指向前驅節點threadNodes(node.leftNode);// 處理前驅節點if (node.leftNode == null) {// 讓當前節點的左指針指向前驅節點node.leftNode = pre;// 改變當前節點左指針的類型node.leftType = 1;// 指向前驅節點}// 處理前驅的右指針,如果前驅節點的右指針是null(沒有指向右子樹)if (pre != null && pre.rightNode == null) {// 讓前驅節點的右指針指向當前節點pre.rightNode = node;// 改變前驅節點的右指針類型pre.rightType = 1;}// 每處理一個節點,當前節點是下一個節點的前驅節點pre = node;// 處理右子樹threadNodes(node.rightNode);}// 獲取根節點public ThreadedNode getRoot() {return root;}// 前序遍歷public void frontShow() {if (root != null) {root.frontShow();}}// 中序遍歷public void midShow() {if (root != null) {root.midShow();}}// 后序遍歷public void afterShow() {if (root != null) {root.afterShow();}}// 前序查找public ThreadedNode frontSearch(int i) {return root.frontSearch(i);}// 刪除子樹public void delete(int i) {if (root.value == i) {root = null;} else {root.delete(i);}}}

3、ThreadedNode.java

package demo7;public class ThreadedNode {int value;// 節點的權ThreadedNode leftNode;// 左兒子ThreadedNode rightNode;// 右兒子// 標識指針類型-默認值為0,指向左右子樹int leftType;int rightType;public ThreadedNode(int value) {this.value = value;}// 設置左兒子public void setLeftNode(ThreadedNode leftNode) {this.leftNode = leftNode;}// 設置右兒子public void setRightNode(ThreadedNode rightNode) {this.rightNode = rightNode;}// 前序遍歷public void frontShow() {// 先遍歷當前節點的內容System.out.println(value);// 左節點if (leftNode != null) {leftNode.frontShow();}// 右節點if (rightNode != null) {rightNode.frontShow();}}// 中序遍歷public void midShow() {// 左子節點if (leftNode != null) {leftNode.midShow();}// 當前節點System.out.print(value + "、");// 右子節點if (rightNode != null) {rightNode.midShow();}}// 后序遍歷public void afterShow() {// 左子節點if (leftNode != null) {leftNode.afterShow();}// 右子節點if (rightNode != null) {rightNode.afterShow();}// 當前節點System.out.println(value);}// 前序查找public ThreadedNode frontSearch(int i) {ThreadedNode target = null;// 對比當前節點的值if (this.value == i) {return this;// 當前節點的值不是要查找的節點} else {// 查找左兒子if (leftNode != null) {// 有可能可以查到,也可以查不到,查不到的話,target還是一個nulltarget = leftNode.frontSearch(i);}// 如果不為空,說明在左兒子中已經找到if (target != null) {return target;}// 查找右兒子if (rightNode != null) {target = rightNode.frontSearch(i);}}return target;}// 刪除一個子樹public void delete(int i) {ThreadedNode parent = this;// 判斷左兒子if (parent.leftNode != null && parent.leftNode.value == i) {parent.leftNode = null;return;}// 判斷右兒子if (parent.rightNode != null && parent.rightNode.value == i) {parent.rightNode = null;return;}// 遞歸檢查并刪除左兒子parent = leftNode;if (parent != null) {parent.delete(i);}// 遞歸檢查并刪除右兒子parent = rightNode;if (parent != null) {parent.delete(i);}}}

P39-4.12線索二叉樹的遍歷

不需要 使用 遞歸!!!

總結

以上是生活随笔為你收集整理的数据结构Java05【二叉树概述、二叉树遍历、堆排序、线索二叉树实现及遍历】的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。