一,插入数据
二叉树的插入过程
数据结构
typedef struct TreeNode {
int data;
struct TreeNode *leftchild;
struct TreeNode *rightChild;
struct TreeNode *parent;
}TreeNode;
1, 第一步判断二叉树是否有根节点
//判断根节点是否为空
if (root == NULL) {
//创建根节点
root = (TreeNode *)malloc(sizeof(TreeNode));
//赋值
root->data = data;
root->leftchild = NULL;
root->rightChild = NULL;
return root;
}
2, 如果有节点就记录当前的根节点,遍历比较节点的数据大小, 添加节点
//遍历比较
TreeNode *parent = NULL;
TreeNode *node = root;
//遍历遍历比较大小 , 查询找到插入的位置
for (; node != NULL; ) {
parent = node;
//比较值
if (data < parent->data)
node = parent->leftchild;
else if (data > parent->data)
node = parent->rightChild;
else
return node;
}
//创建节点
TreeNode* newNode = (TreeNode *)malloc(sizeof(TreeNode));
//赋值操作
newNode->data = data;
newNode->leftchild = NULL;
newNode->rightChild = NULL;
if (data < parent->data) {
parent->leftchild = newNode;
}
else {
parent->rightChild = newNode;
}
//child指针父节点parent
newNode->parent = parent;
二,前序,中序, 后续遍历
提一下遍历的定义:
- 前序遍历: DLR , 先根,在左, 再右
- 中序遍历:LDR,先左,在根, 再右
- 后序遍历:LRD, 先左, 在右,在根
前序遍历
LRD
void modleOrderTraverse(TreeNode *node) {
if (node == NULL)
return;
printf("%d\t", node->data);
modleOrderTraverse(node->leftchild);
modleOrderTraverse(node->rightChild);
}
中序遍历
LDR
void midOrderTraverse(TreeNode* node) {
if (node == NULL)
return;
midOrderTraverse(node->leftchild);
printf("%d\t", node->data);
midOrderTraverse(node->rightChild);
}
后序遍历
若二叉树为空则结束返回,
否则:
(1)后序遍历左子树
(2)后序遍历右子树
(3)访问根结点
LRD
void maxOrderTraverse(TreeNode* node) {
if (node == NULL)
return;
midOrderTraverse(node->leftchild);
midOrderTraverse(node->leftchild);
printf("%d\t", node->data);
}
三,删除一个节点的操作
删除一个节点分为: 四种情况
1. 没有左右孩子节点的树的情况
2. 有左孩子的节点的树的情况
3. 有右孩子的节点的树的情况
4. 有左右孩子的节点的树的情况
1,第一种情况的分析没有左右节点的树情况
可以分为两种情况
- 是根(root)节点情况
- 不是节点的情况, 是叶子节点情况
①是根节点的情况图
//父节点为空时
if (parent == NULL) {
root = NULL; //置空
}
②,不是根节点的情况是叶子结点情况
if (parent->leftchild == node) {
parent->leftchild = node->rightChild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
}
二,第二种情况和第三情况
只有左孩子或者右孩子的节点
大致也分为两类
1. 是根节点
2. 不是根节点,是只有左孩子或者右或者情况的节点
①,是根(root)节点的情况
//判r断父节点
if (parent == NULL) {
root = parent->leftchild;
}
②,不是根节点的情况,只有左孩子或者右或者情况的节点
实现:
if (parent->leftchild == node) {
parent->leftchild = node->leftchild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
}
三,第四情况
分为两个大的情况
- 节点right节点的left为空的情况(node->rightChild->left == NULL)
- 节点的right节点的left不为空的情况(node->rightCild->left != NULL)
①,第一种情况 (node->rightChild->left == NULL)
在这种情况下面也分为两种情况
1. 是根节点
2. 不是根节点,是只有左孩子或者右或者情况的节点
if (parent->rightChild->leftchild == NULL) {
node->rightChild->leftchild = node->rightChild;
if (parent == NULL) {
root = node->rightChild;
}
else if (parent->leftchild == node) {
parent->leftchild = node->leftchild;
//parent->leftchild->rightChild = node->rightChild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
//parent->rightChild->leftchild = node->rightChild;
}
}
②第二种情况(node->rightChild->leftChild != NULL)
TreeNode *leftNode = MinTreeNode(node->rightChild);
//第一步
leftNode->leftchild = node->leftchild;
//第二步
TreeNode* leftNodep = leftNode->parent;
leftNodep->leftchild = leftNode->rightChild;
//第三步
leftNode->rightChild = node->rightChild;
//第四步
if (parent == NULL)
root = leftNode;
else {
if (parent->leftchild == node)
parent->leftchild = leftNode;
else if (parent->rightChild == node)
parent->rightChild = leftNode;
//leftNode->parent = parent;
}
}
C语言的代码实现
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode {
int data;
struct TreeNode *leftchild;
struct TreeNode *rightChild;
struct TreeNode *parent;
}TreeNode;
//根节点
TreeNode *root = NULL;
//添加节点
TreeNode* put(int data) {
//判断根节点是否为空
if (root == NULL) {
//创建根节点
root = (TreeNode *)malloc(sizeof(TreeNode));
//赋值
root->data = data;
root->leftchild = NULL;
root->rightChild = NULL;
return root;
}
//遍历比较
TreeNode *parent = NULL;
TreeNode *node = root;
//遍历遍历比较大小 ,查询找到插入的位置
for (; node != NULL; ) {
parent = node;
//比较值
if (data < parent->data)
node = parent->leftchild;
else if (data > parent->data)
node = parent->rightChild;
else
return node;
}
//创建节点
TreeNode* newNode = (TreeNode *)malloc(sizeof(TreeNode));
//赋值操作
newNode->data = data;
newNode->leftchild = NULL;
newNode->rightChild = NULL;
if (data < parent->data) {
parent->leftchild = newNode;
}
else {
parent->rightChild = newNode;
}
//child指针父节点parent
newNode->parent = parent;
return newNode;
}
/**
* 中序遍历
*/
void midOrderTraverse(TreeNode* node) {
if (node == NULL)
return;
midOrderTraverse(node->leftchild);
printf("%d\t", node->data);
midOrderTraverse(node->rightChild);
}
/**
* 后序遍历
*/
void maxOrderTraverse(TreeNode* node) {
if (node == NULL)
return;
midOrderTraverse(node->leftchild);
midOrderTraverse(node->leftchild);
printf("%d\t", node->data);
}
/*
前序遍历
*/
void modleOrderTraverse(TreeNode *node) {
if (node == NULL)
return;
printf("%d\t", node->data);
modleOrderTraverse(node->leftchild);
modleOrderTraverse(node->rightChild);
}
TreeNode * MinTreeNode(TreeNode *node) {
if (node == NULL) {
printf("方法名:%s\n", __FUNCTION__);
return NULL;
}
else {
while (node->leftchild != NULL) {
node = node->leftchild;
}
return node;
}
}
/*
删除一个节点
*/
void delNode(TreeNode *node) {
if (node == NULL) {
printf("node == null\n");
}
else {
TreeNode *parent = node->parent;
//1, 没有孩子
if ((node->rightChild == NULL) && (node->leftchild == NULL)) {
//父节点为空时
if (parent == NULL) {
root = NULL;
}
else {
if (parent->leftchild == node) {
parent->leftchild = node->rightChild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
}
}
//释放节点的内存
free(node);
//节点数据置空
node->data = NULL;
//父指针
node->parent = NULL;
node = NULL;
}
else if ((node->rightChild == NULL) && (node->leftchild != NULL)) {
//2, 有左孩子
//判r断父节点
if (parent == NULL) {
root = parent->leftchild;
}
else {
if (parent->leftchild == node) {
parent->leftchild = node->leftchild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
}
}
//释放节点的内存
free(node);
//节点数据置空
node->data = NULL;
//父指针
node->parent = NULL;
node = NULL;
}
else if ((node->rightChild != NULL) && (node->leftchild == NULL)) {
//3, 有右孩子
//判断父节点
if (parent == NULL) {
root = parent->rightChild;
//parent->rightChild->parent = NULL;
}
else {
if (parent->leftchild == node) {
parent->leftchild = node->rightChild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->rightChild;
}
}
//释放节点的内存
free(node);
//节点数据置空
node->data = NULL;
//父指针
node->parent = NULL;
node = NULL;
}
else if ((node->rightChild != NULL) && (node->leftchild != NULL)) {
//4, 有左右孩子
if (parent->rightChild->leftchild == NULL) {
node->rightChild->leftchild = node->rightChild;
if (parent == NULL) {
root = node->rightChild;
}
else if (parent->leftchild == node) {
parent->leftchild = node->leftchild;
//parent->leftchild->rightChild = node->rightChild;
}
else if (parent->rightChild == node) {
parent->rightChild = node->leftchild;
//parent->rightChild->leftchild = node->rightChild;
}
}
else {
TreeNode *leftNode = MinTreeNode(node->rightChild);
//第一步
leftNode->leftchild = node->leftchild;
//第二步
TreeNode* leftNodep = leftNode->parent;
leftNodep->leftchild = leftNode->rightChild;
//第三步
leftNode->rightChild = node->rightChild;
//第四步
if (parent == NULL)
root = leftNode;
else {
if (parent->leftchild == node)
parent->leftchild = leftNode;
else if (parent->rightChild == node)
parent->rightChild = leftNode;
//leftNode->parent = parent;
}
}
//释放节点的内存
free(node);
//节点数据置空
node->data = NULL;
//父指针
node->parent = NULL;
node = NULL;
}
}
}
TreeNode* searchNode(int data) {
if (root == NULL) {
return NULL;
}
TreeNode* node = root;
while (node != NULL) {
if (node->data == data) {
return node;
}
else if (node->data < data) {
node = node->rightChild;
}
else if (node->data > data) {
node = node->leftchild;
}
}
return NULL;
}
int main(int argc, char* argv[])
{
int arrays[] = {12, 3, 23, 5, 8, 1, 19, 2, 4, 56, 45, 34, 23, 33};
for (int i = 0; i < 14; i++)
put(arrays[i]);
printf("中序遍历\n");
midOrderTraverse(root);
printf("\n");
printf("前序遍历\n");
printf("\n");
modleOrderTraverse(root);
printf("\n");
printf("后序遍历\n");
printf("\n");
maxOrderTraverse(root);
TreeNode * del = searchNode(33);
delNode(del);
printf("\n");
midOrderTraverse(root);
//modleOrderTraverse(root);
printf("\n");
system("pause");
return EXIT_SUCCESS;
}
Java代码的实现
package com.songli.BinarayTree;
import java.util.NoSuchElementException;
import com.sun.jmx.snmp.BerException;
/**
> Author: songli
> QQ: 2734030745
> Mail: 15850774503@163.com
> 优快云: http://my.youkuaiyun.com/Poisx
> github: https://github.com/chensongpoixs
*/
public class SearchBinaryTree {
//根节点
public TreeNode root;
public class TreeNode {
int data;
TreeNode leftChild;
TreeNode rightChild;
TreeNode parent;
/**
* @return the data
*/
public int getData() {
return data;
}
/**
* @param data the data to set
*/
public void setData(int data) {
this.data = data;
}
/**
* @return the leftChild
*/
public TreeNode getLeftChild() {
return leftChild;
}
/**
* @param leftChild the leftChild to set
*/
public void setLeftChild(TreeNode leftChild) {
this.leftChild = leftChild;
}
/**
* @return the rightChild
*/
public TreeNode getRightChild() {
return rightChild;
}
/**
* @param rightChild the rightChild to set
*/
public void setRightChild(TreeNode rightChild) {
this.rightChild = rightChild;
}
/**
* @return the parent
*/
public TreeNode getParent() {
return parent;
}
/**
* @param parent the parent to set
*/
public void setParent(TreeNode parent) {
this.parent = parent;
}
/**
* 构造器
* @param data
* @param leftChild
* @param rightChild
* @param parent
*/
public TreeNode(int data) {
super();
this.data = data;
this.leftChild = null;
this.rightChild = null;
this.parent = null;
}
}
public TreeNode getRoot() {
return root;
}
/**
* 添加节点
* @param data
* @return
*/
public TreeNode put(int data) {
//判断根节点是否为空
if (root == null){
//创建节点
TreeNode node = new TreeNode(data);
//赋值给根节点
root = node;
return node; //返回节点
}
//遍历比较
TreeNode parent = null;
//得到根节点
TreeNode node = root;
//遍历比较节点的大小
for (; node != null; ) {
parent = node;
//比较当前节点的值
if (data < node.data) {
node = node.leftChild;
} else if(data > node.data) {
node = node.rightChild;
} else {
//相等情况返回
return node;
}
}
//添加节点
TreeNode newNode = new TreeNode(data);
if (data < parent.data) {
parent.leftChild = newNode;
} else {
parent.rightChild = newNode;
}
//child指针父节点parent
newNode.parent = parent;
return newNode;
}
/**
* 前序遍历
* @param root
*/
public void preOrderTraverse(TreeNode root) {
if (root == null)
return;
System.out.println("pro Order : " + root.data);
preOrderTraverse(root.leftChild);
preOrderTraverse(root.rightChild);
}
/**
* 中序遍历 时间复杂度 :O(n)
* @param root
*/
public void midOrderTraverse(TreeNode root) {
if (root == null)
return;
midOrderTraverse(root.leftChild);
System.out.print(root.data + " ");
midOrderTraverse(root.rightChild);
}
/**
*
* @param data
* @return
*/
public TreeNode searchNode(int data) {
if (root == null)
return null;
//比较right和left节点的大小
TreeNode node = root;
//在java中不要使用 递归
while (node != null) {
//比较当前节点
if (node.data == data)
return node;
else if (node.data < data)
node = node.rightChild;
else if (node.data > data)
node = node.leftChild;
}
//不存节点在返回null
return null;
}
/**
* 删除一个节点
* @param node
*/
private void delNode(TreeNode node) {
if (node == null) {
//异常报错历 没有成
throw new NoSuchElementException();
} else {
TreeNode parent = node.parent;
//1,没有right 和left 子树
if ((node.leftChild == null) && (node.rightChild == null)) {
//判断父节点是否为空
if (parent == null) {
root = null;
} else if (parent.leftChild == node) {
parent.leftChild = null;
} else if (parent.rightChild == node) {
parent.rightChild = null;
}
node.parent = null;
} else if ((node.leftChild != null) && (node.rightChild == null)) {
//2,有left子树
if (parent == null) {
node.parent = null;
parent.leftChild.parent = null; //改变孩子的指针
root = node.leftChild;
} else {
if (parent.leftChild == node) {
parent.leftChild = node.leftChild;
} else if (parent.rightChild == node) {
parent.rightChild = node.rightChild;
}
node.parent = null;
}
} else if ((node.leftChild == null) && (node.rightChild != null)) {
//3,有ringht子树
if (parent == null) {
node.parent = null;
parent.rightChild.parent = null; //改变孩子的指针
root = node.rightChild;
} else {
if (parent.leftChild == node) {
parent.leftChild = node.leftChild;
} else if (parent.rightChild == node) {
parent.rightChild = node.rightChild;
}
node.parent = null;
}
} else if ((node.leftChild != null) && (node.rightChild != null)) {
//4,有letf, ringht树
if (node.rightChild.leftChild == null) {
if (parent == null) {
root = node.rightChild;
} else {
if (parent.leftChild == node) {
parent.leftChild = node.rightChild;
} else if (parent.rightChild == node) {
parent.rightChild = node.rightChild;
}
}
node.parent = null;
} else {
TreeNode newleftNode = MinleftNode(node.rightChild);
//第一步
newleftNode.leftChild = node.leftChild;
//第二步
TreeNode newleftNodeP = newleftNode.parent;
newleftNodeP.leftChild = newleftNode.rightChild;
//第三步
newleftNode.rightChild = node.rightChild;
//第四步
if (parent == null) {
root = newleftNode;
} else {
if (parent.leftChild == node) {
parent.leftChild = newleftNode;
} else if (parent.rightChild == node) {
parent.rightChild = newleftNode;
}
}
}
//node.parent = null;
//node = null;
}
}
}
/**
* @param rightChild
* @return
*/
private TreeNode MinleftNode(TreeNode node) {
// TODO Auto-generated method stub
if (node == null) {
return null;
} else {
while (node.leftChild != null) {
node = node.leftChild;
}
return node;
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
int arrays[] = {12, 3, 23, 5, 8, 1, 19, 2, 4, 56, 45, 34, 23, 33};
SearchBinaryTree tree = new SearchBinaryTree();
for (int i: arrays)
tree.put(i);
//打印
tree.midOrderTraverse(tree.root);
//查找树
TreeNode node = tree.searchNode(23);
//System.out.println(node != null ? node.data: null);
System.out.println();
tree.delNode(node);
//打印
tree.midOrderTraverse(tree.root);
}
}