Kotlin遇見數據結構丨說說如何中序線索化二叉樹

Kotlin遇見數據結構丨說說如何中序線索化二叉樹

線索二叉樹

n個節點的二叉樹含有n+1個空指針域。利用這些空指針域,存放指向節點的在某種遍歷次序下的前驅節點及後繼節點的指針,這種附加的指針稱為"線索",加上了線索的二叉樹就是"線索二叉樹"。

根據線索性質的不同,線索二叉樹可分為前序線索二叉樹、中序線索二叉樹和後序線索二叉樹三種。

線索化二叉樹的本質是將一個複雜的非線性結構轉換為線性結構,使每一個節點都有了唯一的前驅節點和後續節點(第一個節點無前驅,最後一個節點無後繼)。

前驅節點:線索化二叉樹時,某節點的前一個節點叫前驅節點

後繼節點:線索化二叉樹時,某節點的後一個節點叫後繼節點

Kotlin 中如何線索化二叉樹

 /**
 * 中序線索化二叉樹
 * */
 fun midThreadNodes(node:ThreadTreeNode?){

 // 當遞歸到最右側葉子結點則結束
 if (null == node){
 return
 }

 // 處理左子樹
 midThreadNodes(node?.leftNode)

 // ① 處理左指針
 if (null == node.leftNode){
 // 賦值前驅節點
 node.leftNode = preNode
 // 改變當前節點左指針類型
 node.leftType = 1
 }

 // ② 處理前驅節點的右指針,如果上一個節點的右子節點為null
 if (null != preNode && preNode?.rightNode == null){
 // 讓前驅節點的右指針指向當前節點
 preNode?.rightNode = node
 // 修改前驅節點的右指針類型
 preNode?.rightType = 1
 }

 // ③ 處理右指針,存儲當前節點為下一個節點的前驅節點
 preNode = node

 // 處理右子樹
 midThreadNodes(node?.rightNode)
 }
 

Kotlin 中線索二叉樹如何遍歷

 /**
 * 遍歷線索二叉樹
 * */
 fun iterateTree(){

 var root:ThreadTreeNode? = rootNode

 // 循環遍歷,直到最後一個節點
 while (null != root){

 // 循環找到最左側節點
 while (root?.leftType == 0){
 root = root.leftNode
 }

 // 打印最左側節點的節點權
 Log.e("==",""+root?.value)

 // 判斷最左側節點是否存在後繼節點,有則持續打印節點權
 while (root?.rightType == 1){
 root = root?.rightNode
 Log.e("==",""+root?.value)
 }

 // 替換遍歷節點
 root = root?.rightNode
 }
 }

運行結果

Kotlin遇見數據結構丨說說如何中序線索化二叉樹

國際慣例

貼上完整源碼

ThreadBianryTree.kt

/**
 * @des 線索二叉樹Bean
 * @author liyongli 20190221
 *
 * @param rootNode : 二叉樹的根節點
 * @param preNode : 臨時存儲的前驅節點
 * */
data class ThreadBianryTree(var rootNode: ThreadTreeNode?, var preNode:ThreadTreeNode? = null) {

 /**
 * 遍歷線索二叉樹
 * */
 fun iterateTree(){

 var root:ThreadTreeNode? = rootNode
 // 循環遍歷,直到最後一個節點

 while (null != root){
 // 循環找到最左側節點
 while (root?.leftType == 0){
 root = root.leftNode
 }

 // 打印節點權
 ThreadBinaryTreeActivity.afterResult.append(root?.value).append(" ")

 // 判斷是否存在後繼節點,有則持續打印節點權
 while (root?.rightType == 1){
 root = root?.rightNode
 ThreadBinaryTreeActivity.afterResult.append(root?.value).append(" ")
 }

 // 替換遍歷節點
 root = root?.rightNode

 }
 }

 /**
 * 中序線索化二叉樹
 * */
 fun threadNodes(){
 midThreadNodes(rootNode)
 }

 /**
 * 中序線索化二叉樹
 * */
 fun midThreadNodes(node:ThreadTreeNode?){

 // 當遞歸到最右側葉子結點則結束
 if (null == node){
 return
 }

 // 處理左子樹
 midThreadNodes(node?.leftNode)

 // ① 處理左指針
 if (null == node.leftNode){
 // 賦值前驅節點
 node.leftNode = preNode
 // 改變當前節點左指針類型
 node.leftType = 1
 }

 // ② 處理前驅節點的右指針,如果上一個節點的右子節點為null
 if (null != preNode && preNode?.rightNode == null){
 // 讓前驅節點的右指針指向當前節點
 preNode?.rightNode = node
 // 修改前驅節點的右指針類型
 preNode?.rightType = 1
 }

 // ③ 處理右指針,存儲當前節點為下一個節點的前驅節點
 preNode = node

 // 處理右子樹
 midThreadNodes(node?.rightNode)

 }
}

ThreadBinaryTreeActivity.kt

/**
 * @des 線索二叉樹Bean
 * @author liyongli 20190221
 *
 * @param rootNode : 二叉樹的根節點
 * @param preNode : 臨時存儲的前驅節點
 * */
data class ThreadBianryTree(var rootNode: ThreadTreeNode?, var preNode:ThreadTreeNode? = null) {

 /**
 * 遍歷線索二叉樹
 * */
 fun iterateTree(){

 var root:ThreadTreeNode? = rootNode

 // 循環遍歷,直到最後一個節點
 while (null != root){

 // 循環找到最左側節點
 while (root?.leftType == 0){
 root = root.leftNode
 }

 // 打印節點權
 ThreadBinaryTreeActivity.afterResult.append(root?.value).append(" ")

 // 判斷是否存在後繼節點,有則持續打印節點權
 while (root?.rightType == 1){
 root = root?.rightNode
 ThreadBinaryTreeActivity.afterResult.append(root?.value).append(" ")
 }

 // 替換遍歷節點
 root = root?.rightNode

 }
 }

 /**
 * 中序線索化二叉樹
 * */
 fun threadNodes(){
 midThreadNodes(rootNode)
 }

 /**
 * 中序線索化二叉樹
 * */
 fun midThreadNodes(node:ThreadTreeNode?){

 // 當遞歸到最右側葉子結點則結束
 if (null == node){
 return
 }

 // 處理左子樹
 midThreadNodes(node?.leftNode)

 // ① 處理左指針
 if (null == node.leftNode){
 // 賦值前驅節點
 node.leftNode = preNode
 // 改變當前節點左指針類型
 node.leftType = 1
 }

 // ② 處理前驅節點的右指針,如果上一個節點的右子節點為null
 if (null != preNode && preNode?.rightNode == null){
 // 讓前驅節點的右指針指向當前節點
 preNode?.rightNode = node
 // 修改前驅節點的右指針類型
 preNode?.rightType = 1
 }

 // ③ 處理右指針,存儲當前節點為下一個節點的前驅節點
 preNode = node

 // 處理右子樹
 midThreadNodes(node?.rightNode)
 }
}
 

本篇到此完結,更多Kotlin與數據結構原創內容持續更新中~

期待您點擊關注或點擊頭像瀏覽更多移動端開發技術乾貨


Kotlin遇見數據結構丨說說如何中序線索化二叉樹



分享到:


相關文章: