06_线索二叉树实现(c java)
·
06_线索二叉树
6.1 介绍
现有一个结点数目为n的二叉树,采用二叉链表的形式存储,对于每个结点均有指向左右孩子的两个指针域。
结点为n的二叉树一共有 n + 1 个空指针域。

线索二叉树:先对二叉树中序化,中序线索化,建立虚线以后,再进行前驱后继的处理,就直接按照线索化的路径进行遍历。
中序遍历:1. 一直往左走,直到找到左线索点。2. 当前这个点是否有右线索,一直往右。3. 当发现某个点的右边不是线索化点,把这个右边的点当作新结点,重复1. 。

6.2 申明
由于左右指针域,既可能表示节点,也可能线索化,因此添加标记Tag,来辅助表示。
c 实现:
typedef char Element_t;
//定义线索二叉树节点结构
typedef struct treenode {
Element_t data;
struct treenode* left;
struct treenode* right;
int leftTag; //0表示left指向节点,1表示线索化(前驱)
int rightTag; //0表示right指向节点,1表示线索化(后继)
}TreeNode_t;
//定义线索二叉树结构
typedef struct {
TreeNode_t* root;
int count;
}ThreadedBinaryTree_t;
Java 实现:
Element:
package com.Sonnet.Threaded;
public class Element {
private char data;
public Element() {}
public Element(char data) {
this.data = data;
}
@Override
public String toString() {
return String.valueOf(data);
}
@Override
public int hashCode() {
return Integer.hashCode(data);
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (this.getClass() != obj.getClass()) return false;
Element other = (Element)obj;
return this.data == other.data;
}
}
TreeNode:
package com.Sonnet.Threaded;
public class TreeNode {
Element data;
TreeNode left;
TreeNode right;
//false 表示left指向节点,true 表示线索化(前驱)
boolean leftTag;
//false 表示right指向节点,true 表示线索化(后继)
boolean rightTag;
public TreeNode() {}
public TreeNode(Element data) {
this.data = data;
this.left = null;
this.right = null;
this.leftTag = false;
this.rightTag = false;
}
}
ThreadedBinaryTree:
package com.Sonnet.Threaded;
public class ThreadedBinaryTree {
TreeNode root;
int count;
}
6.3 创建
c 实现:
/*创建节点*/
TreeNode_t* createTreeNode(Element_t data) {
TreeNode_t* node = malloc(sizeof(TreeNode_t));
if (node == NULL) {
printf("malloc failed\n");
return NULL;
}
//初始化
node->data = data;
node->left = NULL;
node->right = NULL;
node->leftTag = 0;
node->rightTag = 0;
return node;
}
/*创建线索二叉树*/
ThreadedBinaryTree_t* createThreadedBinaryTree(TreeNode_t* root) {
if (root == NULL) return NULL;
ThreadedBinaryTree_t* tree = malloc(sizeof(ThreadedBinaryTree_t));
if (tree == NULL) {
printf("malloc failed\n");
return NULL;
}
//初始化
tree->count = 1;
tree->root = root;
return tree;
}
Java 实现:
public ThreadedBinaryTree() {}
public ThreadedBinaryTree(TreeNode root) {
private this.root = root;
private this.count = 1;
}
6.4 插入
c 实现:
/*插入*/
void insertTreeNode(ThreadedBinaryTree_t* tree, TreeNode_t* parent, TreeNode_t* left, TreeNode_t* right) {
if (tree == NULL || parent == NULL) return;
if (left) {
parent->left = left;
tree->count++;
}
if (right) {
parent->right = right;
tree->count++;
}
return;
}
Java 实现:
/*
功能: 插入
参数: 父亲节点 左孩子 右孩子
返回值: 无
*/
public void insertTreeNode(TreeNode parent, TreeNode left, TreeNode right) {
if (parent == null) return;
if (left != null) {
parent.left = left;
this.count++;
}
if (right != null) {
parent.right = right;
this.count++;
}
}
6.5 访问
c 实现:
/*访问*/
void visitTreeNode(TreeNode_t* node) {
if (node == NULL) return;
printf("%c\t", node->data);
}
Java 实现:
/*
功能: 访问节点
参数: 节点
返回值: 无
*/
public void visitTreeNode(TreeNode node) {
if (node == null) return;
System.out.print(node.data + "\t");
}
6.6 线索化
c 实现:
/*线索化节点*/
static TreeNode_t* pre = NULL;
void inOrderTreeNode(TreeNode_t* node) {
//递归退出条件
if (node == NULL) return;
//访问左孩子
inOrderTreeNode(node->left);
//线索化
if (node->left == NULL) {
node->left = pre;
node->leftTag = 1;
}
if (pre && pre->right == NULL) {
pre->right = node;
pre->rightTag = 1;
}
pre = node;
//访问右孩子
inOrderTreeNode(node->right);
}
/*线索化*/
void inOrderThreadingBinaryTree(ThreadedBinaryTree_t* tree) {
inOrderTreeNode(tree->root);
}
Java 实现:
private TreeNode pre = null;
private void inOrderTreeNode(TreeNode node) {
//递归退出条件
if (node == null) return;
inOrderTreeNode(node.left);
if (node.left == null) {
node.left = pre;
node.leftTag = true;
}
if (pre != null && pre.right == null) {
pre.right = node;
pre.rightTag = true;
}
pre = node;
inOrderTreeNode(node.right);
}
/*
功能: 线索化二叉树
参数: 无
返回值: 无
*/
public void inOrderThreadingBinaryTree() {
inOrderTreeNode(this.root);
}
6.7 中序遍历线索二叉树
- 一直往左走,直到找到做线索点
- 如果有右线索,一直往右,直到无右线索
- 无右线索时,以右节点为新节点,重复1
c 实现:
/*中序遍历线索二叉树*/
void inOrderThreadedBinaryTree(ThreadedBinaryTree_t* tree) {
TreeNode_t* node = tree->root;
while (node) {
//一路向左
while (node->leftTag == 0) {
node = node->left;
}
//访问头节点
visitTreeNode(node);
//一路向右
while (node->rightTag == 1 && node->right) {
node = node->right;
visitTreeNode(node);
}
node = node->right;
}
printf("\n");
}
Java 实现:
/*
功能: 中序遍历线索二叉树
参数: 无
返回值: 无
*/
public void inOrderThreadedBinaryTree() {
TreeNode node = this.root;
while (node != null) {
//一直往左, 直到左线索点
while (!node.leftTag) {
node = node.left;
}
//访问头节点
visitTreeNode(node);
//一路向右
while (node.rightTag && node.right != null) {
node = node.right;
visitTreeNode(node);
}
//重置头节点
node = node.right;
}
System.out.println();
}
6.8 释放
c 实现:
static void freeTreeNode(ThreadedBinaryTree_t* tree, TreeNode_t* node) {
if (node == NULL) return;
if (node->leftTag == 0) {
freeTreeNode(tree, node->left);
}
if (node->rightTag == 0) {
freeTreeNode(tree, node->right);
}
free(node);
tree->count--;
}
/*释放*/
void releaseThreadedBinaryTree(ThreadedBinaryTree_t* tree) {
freeTreeNode(tree, tree->root);
printf("tree have %d node\n", tree->count);
free(tree);
}
Java 实现:
private void freeTreeNode(TreeNode node) {
if (node == null) return;
if (!node.leftTag) {
freeTreeNode(node.left);
}
if (!node.rightTag) {
freeTreeNode(node.right);
}
node.left = null;
node.right = null;
this.count--;
}
/*
功能: 释放线索二叉树
参数: 无
返回值: 无
*/
public void releaseThreadedBinaryTree() {
freeTreeNode(this.root);
System.out.println("tree have " + this.count + " node");
this.root = null;
}
6.9 完整实现
c 实现:
ThreadedBTree.h:
#pragma once
typedef char Element_t;
//定义线索二叉树节点结构
typedef struct treenode {
Element_t data;
struct treenode* left;
struct treenode* right;
int lTag; //0表示left是指向节点,1表示线索化(前驱)
int rTag; //0表示right是指向节点,1表示线索化(后继)
}TreeNode_t;
//定义二叉线索树结构
typedef struct {
int number;
TreeNode_t* root;
}ThreadedBTree_t;
/*
功能: 创建二叉线索树
参数: 根节点
返回值: 线索二叉树
*/
ThreadedBTree_t* createThreadedBinaryTree(TreeNode_t* root);
/*
功能: 创建节点
参数: 节点数据
返回值: 节点
*/
TreeNode_t* createTreeNode(Element_t element);
/*
功能: 释放二叉线索树
参数: 二叉线索树
返回值: 无
*/
void releaseThreadedBinaryTree(ThreadedBTree_t* tree);
/*
功能: 插入节点
参数: 二叉树, 父亲节点,左孩子,右孩子
返回值:无
*/
void insertTreeNode(ThreadedBTree_t* tree, TreeNode_t* parent, TreeNode_t* left, TreeNode_t* right);
/*
功能: 访问节点数据
参数: 节点
返回值: 无
*/
void visitTreeNode(TreeNode_t* node);
/*
功能: 中序线索化
参数:二叉树
返回值: 无
*/
void inOrderThreadingBinaryTree(ThreadedBTree_t* tree);
/*
功能: 线索化后,开始二叉树的中序遍历
参数: 线索二叉树
返回值: 无
*/
void inOrderTraversal(ThreadedBTree_t* tree);
ThreadedBTree.c:
#include <stdio.h>
#include <stdlib.h>
#include "ThreadedBTree.h"
/*创建二叉树*/
ThreadedBTree_t* createThreadedBinaryTree(TreeNode_t* root) {
if (root == NULL) return NULL;
ThreadedBTree_t* tree = malloc(sizeof(ThreadedBTree_t));
if (tree == NULL) {
printf("malloc failed\n");
return NULL;
}
//初始化
tree->number = 1;
tree->root = root;
return tree;
}
/*创建节点*/
TreeNode_t* createTreeNode(Element_t e) {
TreeNode_t* node = malloc(sizeof(TreeNode_t));
if (node == NULL) {
printf("malloc failed\n");
return NULL;
}
//初始化
node->data = e;
node->left = NULL;
node->right = NULL;
node->lTag = 0;
node->rTag = 0;
return node;
}
/*插入*/
void insertTreeNode(ThreadedBTree_t* tree, TreeNode_t* parent, TreeNode_t* left, TreeNode_t* right) {
if (!tree || !parent) return;
if (left) {
parent->left = left;
tree->number++;
}
if (right) {
parent->right = right;
tree->number++;
}
return;
}
/*访问*/
void visitTreeNode(TreeNode_t* node) {
if (node == NULL) return;
printf("%c\t", node->data);
}
/*线索化节点*/
static TreeNode_t* pre = NULL;
static void inOrderTreeNode(TreeNode_t* node) {
//递归退出条件
if (node == NULL) return;
//访问左孩子
inOrderTreeNode(node->left);
//线索化
if (node->left == NULL) {
node->lTag = 1;
node->left = pre;
}
if (pre && pre->right == NULL) {
pre->right = node;
pre->rTag = 1;
}
pre = node;
//访问右孩子
inOrderTreeNode(node->right);
}
/*线索化二叉树*/
void inOrderThreadingBinaryTree(ThreadedBTree_t* tree) {
inOrderTreeNode(tree->root);
return;
}
/*中序遍历线索二叉树
1. 一直往左走,直到找到左线索点
2. 如果有右线索,一直往右,直到无右线索
3. 无右线索时,以右节点为新节点,重复1
*/
void inOrderTraversal(ThreadedBTree_t* tree) {
TreeNode_t* node = tree->root;
while (node) {
//一直往左走,找到可以作为线索的节点
while (node->lTag != 1) {
node = node->left;
}
//访问头节点
visitTreeNode(node);
//一路向右,
while (node->rTag == 1 && node->right) {
node = node->right;
visitTreeNode(node);
}
//重置node位置,再次循环
node = node->right;
}
printf("\n");
return;
}
/*释放节点*/
static void freeTreeNode(ThreadedBTree_t* tree, TreeNode_t* node) {
if (node == NULL) return;
if (node->lTag == 0) {
freeTreeNode(tree, node->left);
}
if (node->rTag == 0) {
freeTreeNode(tree, node->right);
}
free(node);
tree->number--;
return;
}
/*释放*/
void releaseThreadedBinaryTree(ThreadedBTree_t* tree) {
freeTreeNode(tree, tree->root);
printf("tree have %d node", tree->number);
free(tree);
}
main.c:
#include <stdio.h>
#include "ThreadedBTree.h"
ThreadedBTree_t* init() {
TreeNode_t* nodeA = createTreeNode('A');
TreeNode_t* nodeB = createTreeNode('B');
TreeNode_t* nodeC = createTreeNode('C');
TreeNode_t* nodeD = createTreeNode('D');
TreeNode_t* nodeE = createTreeNode('E');
TreeNode_t* nodeF = createTreeNode('F');
TreeNode_t* nodeG = createTreeNode('G');
TreeNode_t* nodeH = createTreeNode('H');
TreeNode_t* nodeK = createTreeNode('K');
ThreadedBTree_t* tree = createThreadedBinaryTree(nodeA);
insertTreeNode(tree, nodeA, nodeB, nodeE);
insertTreeNode(tree, nodeB, NULL, nodeC);
insertTreeNode(tree, nodeC, NULL, NULL);
insertTreeNode(tree, nodeC, nodeD, NULL);
insertTreeNode(tree, nodeD, NULL, NULL);
insertTreeNode(tree, nodeE, NULL, nodeF);
insertTreeNode(tree, nodeF, nodeG, NULL);
insertTreeNode(tree, nodeG, nodeH, nodeK);
return tree;
}
int main() {
ThreadedBTree_t* tree;
tree = init();
printf("tree have %d node\n", tree->number);
inOrderThreadingBinaryTree(tree);
inOrderTraversal(tree);
releaseThreadedBinaryTree(tree);
return 0;
}
Java 实现:
Element:
package com.Sonnet.Threaded;
public class Element {
private char data;
public Element() {}
public Element(char data) {
this.data = data;
}
@Override
public String toString() {
return String.valueOf(data);
}
@Override
public int hashCode() {
return Integer.hashCode(data);
}
@Override
public boolean equals(Object obj) {
if (obj == this) return true;
if (this.getClass() != obj.getClass()) return false;
Element other = (Element)obj;
return this.data == other.data;
}
}
TreeNode:
package com.Sonnet.Threaded;
public class TreeNode {
Element data;
TreeNode left;
TreeNode right;
//false 表示left指向节点,true 表示线索化(前驱)
boolean leftTag;
//false 表示right指向节点,true 表示线索化(后继)
boolean rightTag;
public TreeNode() {}
public TreeNode(Element data) {
this.data = data;
this.left = null;
this.right = null;
this.leftTag = false;
this.rightTag = false;
}
}
ThreadedBinaryTree:
package com.Sonnet.Threaded;
public class ThreadedBinaryTree {
private TreeNode root;
private int count;
public ThreadedBinaryTree() {}
public ThreadedBinaryTree(TreeNode root) {
this.root = root;
this.count = 1;
}
/*
功能: 插入
参数: 父亲节点 左孩子 右孩子
返回值: 无
*/
public void insertTreeNode(TreeNode parent, TreeNode left, TreeNode right) {
if (parent == null) return;
if (left != null) {
parent.left = left;
this.count++;
}
if (right != null) {
parent.right = right;
this.count++;
}
}
/*
功能: 访问节点
参数: 节点
返回值: 无
*/
public void visitTreeNode(TreeNode node) {
if (node == null) return;
System.out.print(node.data + "\t");
}
private TreeNode pre = null;
private void inOrderTreeNode(TreeNode node) {
//递归退出条件
if (node == null) return;
inOrderTreeNode(node.left);
if (node.left == null) {
node.left = pre;
node.leftTag = true;
}
if (pre != null && pre.right == null) {
pre.right = node;
pre.rightTag = true;
}
pre = node;
inOrderTreeNode(node.right);
}
/*
功能: 线索化二叉树
参数: 无
返回值: 无
*/
public void inOrderThreadingBinaryTree() {
inOrderTreeNode(this.root);
}
/*
功能: 中序遍历线索二叉树
参数: 无
返回值: 无
*/
public void inOrderThreadedBinaryTree() {
TreeNode node = this.root;
while (node != null) {
//一直往左, 直到左线索点
while (!node.leftTag) {
node = node.left;
}
//访问头节点
visitTreeNode(node);
//一路向右
while (node.rightTag && node.right != null) {
node = node.right;
visitTreeNode(node);
}
//重置头节点
node = node.right;
}
System.out.println();
}
private void freeTreeNode(TreeNode node) {
if (node == null) return;
if (!node.leftTag) {
freeTreeNode(node.left);
}
if (!node.rightTag) {
freeTreeNode(node.right);
}
node.left = null;
node.right = null;
this.count--;
}
/*
功能: 释放线索二叉树
参数: 无
返回值: 无
*/
public void releaseThreadedBinaryTree() {
freeTreeNode(this.root);
System.out.println("tree have " + this.count + " node");
this.root = null;
}
}
test:
package com.Sonnet.Threaded;
public class test {
public static void main(String[] args) {
ThreadedBinaryTree tree = initThreadedBinaryTree();
tree.inOrderThreadingBinaryTree();
tree.inOrderThreadedBinaryTree();
tree.releaseThreadedBinaryTree();
}
public static ThreadedBinaryTree initThreadedBinaryTree() {
TreeNode nodeA = new TreeNode(new Element('A'));
TreeNode nodeB = new TreeNode(new Element('B'));
TreeNode nodeC = new TreeNode(new Element('C'));
TreeNode nodeD = new TreeNode(new Element('D'));
TreeNode nodeE = new TreeNode(new Element('E'));
TreeNode nodeF = new TreeNode(new Element('F'));
TreeNode nodeG = new TreeNode(new Element('G'));
TreeNode nodeH = new TreeNode(new Element('H'));
TreeNode nodeK = new TreeNode(new Element('K'));
ThreadedBinaryTree tree = new ThreadedBinaryTree(nodeA);
tree.insertTreeNode(nodeA, nodeB, nodeE);
tree.insertTreeNode(nodeB, null, nodeC);
tree.insertTreeNode(nodeC, null, null);
tree.insertTreeNode(nodeC, nodeD, null);
tree.insertTreeNode(nodeD, null, null);
tree.insertTreeNode(nodeE, null, nodeF);
tree.insertTreeNode(nodeF, nodeG, null);
tree.insertTreeNode(nodeG, nodeH, nodeK);
return tree;
}
}
更多推荐



所有评论(0)