1 平衡二叉树的插入
关于平衡二叉树的定义什么的,就不再多说。直接说说各种功能的c语言实现。 首先插入的时候需要进行旋转以保证树始终保持平衡。而旋转的类型有四种:L-L型旋转,L-R型旋转,R-L型旋转,R-R型旋转。其中L-L型和R-R型只需要进行一次基本旋转操作就可以调整平衡;另外两种需要进行两次方向相反的旋转操作,才能达到目标。四种旋转类型如下:
然后定义两种基本的旋转操作:右旋(顺时针旋转)、左旋(逆时针旋转)。以上图中L-L型为例说明右旋操作。此时应该将节点10右旋,则以节点10的左孩子为轴,将节点10顺时针旋转使其成为其左孩子(节点5)的右孩子。同理,左旋操作应该以当前节点的右孩子为轴,逆时针旋转,使其成为其右孩子的左孩子。下面是两种基本选装操作的函数实现。
//定义节点结构
typedef struct Node {
dataType keyValue; //数据
int BalanceFactor; //平衡因子
struct Node *leftChild, *rightChild;
}*PNode;
//右旋 顺时针旋转
void R_Rotate(PNode* node) {
PNode tmp = (*node)->leftChild;
(*node)->leftChild = tmp->rightChild;
tmp->rightChild = (*node);
(*node) = tmp;
}
//左旋,逆时针旋转
void L_Rotate(PNode* node) {
PNode tmp = (*node)->rightChild;
(*node)->rightChild = tmp->leftChild;
tmp->leftChild = (*node);
(*node) = tmp;
}
四种类型的调整过程为,L-L型:将节点10右旋即可;L-R型:先将节点3左旋。调整为L-L型,再将节点10右旋;R-R型:将节点10左旋即可;R-L型:先将节点20右旋,调整为R-R型,再将节点10左旋即可。整个插入过程就是根据插入后的情况不断进行调整。
具体实现过程:
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
typedef int dataType;
#define EH 0 //左右子树一样高
#define LH 1 //左子树比右子树高
#define RH -1 //右子树比左子树高
//定义节点结构
typedef struct Node {
dataType keyValue; //数据
int BalanceFactor; //平衡因子
struct Node *leftChild, *rightChild;
}*PNode;
//为新建一个节点
PNode createNode(dataType keyValue) {
PNode newNode = (PNode)malloc(sizeof(Node));
newNode->keyValue = keyValue;
newNode->BalanceFactor = EH;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
return newNode;
}
//右旋 顺时针旋转
void R_Rotate(PNode* node) {
PNode tmp = (*node)->leftChild;
(*node)->leftChild = tmp->rightChild;
tmp->rightChild = (*node);
(*node) = tmp;
}
//左旋,逆时针旋转
void L_Rotate(PNode* node) {
PNode tmp = (*node)->rightChild;
(*node)->rightChild = tmp->leftChild;
tmp->leftChild = (*node);
(*node) = tmp;
}
//左边失衡调整
void leftBalance(PNode* node) {
PNode leftchild = (*node)->leftChild;
PNode tmpRightChild = NULL;
switch (leftchild->BalanceFactor)
{
case LH: //LL型失衡
(*node)->BalanceFactor = leftchild->BalanceFactor = EH;
R_Rotate(node);
break;
case RH: //LR型失衡
tmpRightChild = leftchild->rightChild;
switch (tmpRightChild->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = RH;
leftchild->BalanceFactor = EH;
break;
case EH:
(*node)->BalanceFactor = leftchild->BalanceFactor = EH;
break;
case RH:
(*node)->BalanceFactor = EH;
leftchild->BalanceFactor = LH;
break;
}
tmpRightChild->BalanceFactor = EH;
L_Rotate(&(*node)->leftChild);
R_Rotate(node);
break;
}
}
//右边失衡调整
void rightBalance(PNode* node) {
PNode rightchild = (*node)->rightChild;
PNode tmpChild = NULL;
switch (rightchild->BalanceFactor)
{
case RH: //RR型失衡
(*node)->BalanceFactor = rightchild->BalanceFactor = EH;
L_Rotate(node);
break;
case LH: //RL型失衡
tmpChild = rightchild->leftChild;
switch (tmpChild->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = EH;
rightchild->BalanceFactor = RH;
break;
case EH:
(*node)->BalanceFactor = rightchild->BalanceFactor = EH;
break;
case RH:
(*node)->BalanceFactor = EH;
rightchild->BalanceFactor = LH;
break;
}
tmpChild->BalanceFactor = EH;
R_Rotate(&(*node)->rightChild);
L_Rotate(node);
break;
}
}
//插入新值,higher用于判定是否需要调整平衡因子
int InsertKeyValue(PNode* node, dataType keyValue,bool* higher) {
if ((*node) == NULL) { //树中不包含此键值,则新建一个节点,
(*node) = createNode(keyValue);
*higher=true;
}
else if ((*node)->keyValue == keyValue) { //树中已经包含此键值,则不需要插入
*higher = false;
return 0;
}
else if (keyValue < (*node)->keyValue) { //插入到左子树中
if (!InsertKeyValue(&(*node)->leftChild, keyValue, higher)) //如果左子树中存在该节点
return 0;
if (*higher) {
switch ((*node)->BalanceFactor)
{
case LH:
leftBalance(node);
*higher = false;
break;
case RH:
(*node)->BalanceFactor = EH;
*higher = false;
break;
case EH:
(*node)->BalanceFactor = LH;
*higher = true;
break;
}
}
}
else {
if (!InsertKeyValue(&(*node)->rightChild, keyValue,higher)) //如果右子树中存在该节点
return 0;
if (*higher) {
switch ((*node)->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = EH;
*higher = false;
break;
case RH:
rightBalance(node);
*higher = false;
break;
case EH:
(*node)->BalanceFactor = RH;
*higher = true;
break;
}
}
}
return 1;
}
int main()
{
int i, dataArr[] = { 1,23,45,34,98,9,4,35,23,36,37,90,85,80 };
PNode treeRoot = NULL;
bool heigher;
for (i = 0; i < 14; i++) {
InsertKeyValue(&treeRoot, dataArr[i],&heigher);
printfTree(treeRoot);
printf("\n\n");
}
return 0;
}
2 平衡二叉树的遍历
平衡二叉树的遍历一般分为四种:先序、中序、后序和按层次遍历,每种遍历方法都有递归的和非递归的实现方法。
先实现一种按关系遍历的方法,用于检验上面二叉树的构造是否正确吧。
//按关系输出,便于检验数的构造是否正确
void printfTree(PNode root) {
if (root) {
if (root->leftChild) {
printf("%d is %d's left child\n", root->leftChild->keyValue, root->keyValue);
printfTree(root->leftChild);
}
if (root->rightChild) {
printf("%d is %d's right child\n", root->rightChild->keyValue, root->keyValue);
printfTree(root->rightChild);
}
}
}
2.1 中序遍历
中序遍历的递归和非递归实现。所谓中序遍历就是对每个节点的输出顺序都是:左,中,右。递归方法实现很简单:
//中序--递归
void InorderTra(PNode root) {
if (root) {
InorderTra(root->leftChild);
printf("%d\t", root->keyValue);
InorderTra(root->rightChild);
}
}
中序非递归的实现需要利用一个栈。首选需要找到整棵树最左边的节点,并将查过过程中路径上的节点都源栈中,然后,去栈顶元素,输出值,在将其右子树的左节点压入栈。。。。直到栈为空。
//中序--非递归
void InorderTra2(PNode root) {
if (!root) {
printf("树为空!\n");
}
stack<PNode> myStack;
while (root|| !myStack.empty()) { //找到最左边的节点,并将路径上的几点压入栈中
while (root)
{
myStack.push(root);
root = root->leftChild;
}
root = myStack.top(); //取栈顶的值
myStack.pop(); //从栈中删除
printf("%d\t", root->keyValue);
root=root->rightChild;
}
printf("\n");
}
2.2 先序遍历
先序遍历,对每个节点的输出顺序都是:中,左,右。递归实现。
void PreOrderTra(PNode root) {
if (root != NULL) {
printf("%d\t", root->keyValue);
PreOrderTra(root->leftChild);
PreOrderTra(root->rightChild);
}
}
非递归实现。
//前序--非递归
void PreOrderTra2(PNode root) {
if (!root) {
printf("树为空!\n");
}
stack<PNode> myStack;
while (root || !myStack.empty()) {
while (root)
{
myStack.push(root);
printf("%d\t", root->keyValue);
root = root->leftChild;
}
root = myStack.top();
myStack.pop();
root = root->rightChild;
}
printf("\n");
}
2.3 后序遍历
对每个节点的输出顺序都是:左,右,中。递归实现
//后序--递归
void PostOrderTra(PNode root) {
if (root) {
PostOrderTra(root->leftChild);
PostOrderTra(root->rightChild);
printf("%d\t", root->keyValue);
}
}
后序遍历的非递归实现与先序和中序有点不同,每个中间节点都需要被入栈两次,第一次:找到其树的最做节点;第二次:输出左节点之后,需要利用其找到右节点。只有当第二次入栈再取出后才输出具体的值。因为需要用一个标志,标志第几次入栈。具体实现:
//后序--非递归
void PostOrderTra2(PNode root) {
int flag[30]; //用一个标记,标记右子树是否访问过
stack<PNode> myStack;
if (!root) {
printf("树为空!\n");
return;
}
while (root !=NULL ) { //首先将所有的左子树入栈
myStack.push(root);
flag[myStack.size()] = 0;
root = root->leftChild;
}
while (!myStack.empty()) {
root = myStack.top();
if (root->rightChild&&flag[myStack.size()] == 0) { //如果是第一次访问,则还不能输出,需要找到其右子树,将右子树入栈
flag[myStack.size()] = 1;
root = root->rightChild;
while (root)
{
myStack.push(root);
flag[myStack.size()] = 0;
root = root->leftChild;
}
}
root = myStack.top(); //第二次出栈,可以输出了
printf("%d\t", root->keyValue);
myStack.pop();
}
printf("\n");
}
2.4 按层次遍历
按层次遍历即一层层的输出节点值,我这里将根节点视为0层,往下层次依次加1.先定义一个辅助函数,求树的最大深度。
//辅助函数,求树的最大深度
int getDeep(PNode root) {
if (!root) {
return 0;
}
int leftDeep = getDeep(root->leftChild) + 1;
int rightDeep = getDeep(root->rightChild) + 1;
return leftDeep > rightDeep ? leftDeep : rightDeep;
}
然后定义一个函数输出指定层的节点
//输出指定的层,将根节点视为0层
int LevelOrderTra(PNode root,int level) {
if (!root || level < 0) {
printf("%s\t", "NULL");
return 0;
}
if (level == 0) {
printf("%d\t", root->keyValue);
return 1;
}
return LevelOrderTra(root->leftChild, level - 1) + LevelOrderTra(root->rightChild, level - 1);
}
最后输出所有的层
//从根节点开始打印出所有层
void printByLevel(PNode root, int deep) {
for (int i = 0; i < deep; i++) {
LevelOrderTra(root, i);
}
printf("\n");
}
按层输出的非递归方式,利用队列。先访问树的根节点,输出值。然后将其左右孩子分别加入队列。然后取出队头元素,输出值,在将其左右孩子加入队列。。。。。直到队列为空。具体实现:
//法2,利用队列,实现安层次遍历
void printByLevel2(PNode root) {
if (!root) {
printf("树为空!\n");
}
queue<PNode> myQueue;
myQueue.push(root);
while (!myQueue.empty()) {
root = myQueue.front();
myQueue.pop();
printf("%d\t", root->keyValue);
if (root->leftChild)myQueue.push(root->leftChild);
if (root->rightChild) myQueue.push(root->rightChild);
}
}
3 平衡二叉树的查找
相对于插入来说,查找算是非常简单了。平衡二叉树的优点也正是因为其查找效率很高。具体实现。
/*=====================查找===================*/
int SearchTree(PNode root, dataType key) {
if (root->keyValue == key) {
return 1;
}
else if (key > root->keyValue && root->rightChild) {
return SearchTree(root->rightChild, key);
}
else if(key < root->keyValue && root->leftChild) {
return SearchTree(root->leftChild, key);
}
else {
return 0;
}
}
4 平衡二叉树的删除
平衡二叉树的删除思路和二叉排序树相同,只是多了个调整的过程,调整思路和插上相似。这里直接给出代码吧。
/*=======================删除==================*/
bool delNode(PNode &root, dataType key,bool &shorter) {
if (root == NULL) {
return false;
}
else if (key == root->keyValue) {
PNode tmp = NULL;
if (root->leftChild == NULL) {
tmp = root;
root = root->rightChild;
delete tmp;
shorter = true;
}
else if (root->rightChild == NULL) {
tmp = root;
root = root->leftChild;
delete tmp;
shorter = true;
}
else {
tmp = root->leftChild;
while (tmp->rightChild) {
tmp = tmp->rightChild;
}
root->keyValue = tmp->keyValue;
delNode(root->leftChild, tmp->keyValue, shorter);
}
}
else if (key < root->keyValue) {
if (!delNode(root->leftChild, key, shorter)) {
return false;
}
if (shorter) {
switch (root->BalanceFactor)
{
case LH:
root->BalanceFactor = EH;
shorter = true;
break;
case RH:
rightBalance(&root);
if (root->rightChild->BalanceFactor == EH) {
shorter = false;
}
else {
shorter = true;
}
break;
case EH:
root->BalanceFactor = RH;
shorter = false;
break;
}
}
}
else {
if (!delNode(root->rightChild, key, shorter)) {
return false;
}
if (shorter) {
switch (root->BalanceFactor)
{
case LH:
leftBalance(&root);
if (root->leftChild->BalanceFactor == EH) {
shorter = false;
}
else {
shorter = true;
}
break;
case EH:
root->BalanceFactor = LH;
shorter = false;
break;
case RH:
root->BalanceFactor = EH;
shorter = true;
break;
}
}
}
return true;
}
5 整个项目的代码,包括验证部分
// AVLTree.cpp: 定义控制台应用程序的入口点。
//平衡二叉树
//
#include "stdafx.h"
#include<stdio.h>
#include<stdlib.h>
#include<stack>
#include<queue>
using namespace std;
typedef int dataType;
#define EH 0 //左右子树一样高
#define LH 1 //左子树比右子树高
#define RH -1 //右子树比左子树高
//定义节点结构
typedef struct Node {
dataType keyValue; //数据
int BalanceFactor; //平衡因子
struct Node *leftChild, *rightChild;
}*PNode;
//为新建一个节点
PNode createNode(dataType keyValue) {
PNode newNode = (PNode)malloc(sizeof(Node));
newNode->keyValue = keyValue;
newNode->BalanceFactor = EH;
newNode->leftChild = NULL;
newNode->rightChild = NULL;
return newNode;
}
//右旋 顺时针旋转
void R_Rotate(PNode* node) {
PNode tmp = (*node)->leftChild;
(*node)->leftChild = tmp->rightChild;
tmp->rightChild = (*node);
(*node) = tmp;
}
//左旋,逆时针旋转
void L_Rotate(PNode* node) {
PNode tmp = (*node)->rightChild;
(*node)->rightChild = tmp->leftChild;
tmp->leftChild = (*node);
(*node) = tmp;
}
//左边失衡调整
void leftBalance(PNode* node) {
PNode leftchild = (*node)->leftChild;
PNode tmpRightChild = NULL;
switch (leftchild->BalanceFactor)
{
case LH: //LL型失衡
(*node)->BalanceFactor = leftchild->BalanceFactor = EH;
R_Rotate(node);
break;
case RH: //LR型失衡
tmpRightChild = leftchild->rightChild;
switch (tmpRightChild->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = RH;
leftchild->BalanceFactor = EH;
break;
case EH:
(*node)->BalanceFactor = leftchild->BalanceFactor = EH;
break;
case RH:
(*node)->BalanceFactor = EH;
leftchild->BalanceFactor = LH;
break;
}
tmpRightChild->BalanceFactor = EH;
L_Rotate(&(*node)->leftChild);
R_Rotate(node);
break;
}
}
//右边失衡调整
void rightBalance(PNode* node) {
PNode rightchild = (*node)->rightChild;
PNode tmpChild = NULL;
switch (rightchild->BalanceFactor)
{
case RH: //RR型失衡
(*node)->BalanceFactor = rightchild->BalanceFactor = EH;
L_Rotate(node);
break;
case LH: //RL型失衡
tmpChild = rightchild->leftChild;
switch (tmpChild->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = EH;
rightchild->BalanceFactor = RH;
break;
case EH:
(*node)->BalanceFactor = rightchild->BalanceFactor = EH;
break;
case RH:
(*node)->BalanceFactor = EH;
rightchild->BalanceFactor = LH;
break;
}
tmpChild->BalanceFactor = EH;
R_Rotate(&(*node)->rightChild);
L_Rotate(node);
break;
}
}
//插入新值,higher用于判定是否需要调整平衡因子
int InsertKeyValue(PNode* node, dataType keyValue,bool* higher) {
if ((*node) == NULL) { //树中不包含此键值,则新建一个节点,
(*node) = createNode(keyValue);
*higher=true;
}
else if ((*node)->keyValue == keyValue) { //树中已经包含此键值,则不需要插入
*higher = false;
return 0;
}
else if (keyValue < (*node)->keyValue) { //插入到左子树中
if (!InsertKeyValue(&(*node)->leftChild, keyValue, higher)) //如果左子树中存在该节点
return 0;
if (*higher) {
switch ((*node)->BalanceFactor)
{
case LH:
leftBalance(node);
*higher = false;
break;
case RH:
(*node)->BalanceFactor = EH;
*higher = false;
break;
case EH:
(*node)->BalanceFactor = LH;
*higher = true;
break;
}
}
}
else {
if (!InsertKeyValue(&(*node)->rightChild, keyValue,higher)) //如果右子树中存在该节点
return 0;
if (*higher) {
switch ((*node)->BalanceFactor)
{
case LH:
(*node)->BalanceFactor = EH;
*higher = false;
break;
case RH:
rightBalance(node);
*higher = false;
break;
case EH:
(*node)->BalanceFactor = RH;
*higher = true;
break;
}
}
}
return 1;
}
//按关系输出,便于检验数的构造是否正确
void printfTree(PNode root) {
if (root) {
if (root->leftChild) {
printf("%d is %d's left child\n", root->leftChild->keyValue, root->keyValue);
printfTree(root->leftChild);
}
if (root->rightChild) {
printf("%d is %d's right child\n", root->rightChild->keyValue, root->keyValue);
printfTree(root->rightChild);
}
}
}
/*=================================遍历:递归和非递归=========================*/
//中序--递归
void InorderTra(PNode root) {
if (root) {
InorderTra(root->leftChild);
printf("%d\t", root->keyValue);
InorderTra(root->rightChild);
}
}
//中序--非递归
void InorderTra2(PNode root) {
if (!root) {
printf("树为空!\n");
}
stack<PNode> myStack;
while (root|| !myStack.empty()) { //找到最左边的节点,并将路径上的几点压入栈中
while (root)
{
myStack.push(root);
root = root->leftChild;
}
root = myStack.top(); //取栈顶的值
myStack.pop(); //从栈中删除
printf("%d\t", root->keyValue);
root=root->rightChild;
}
printf("\n");
}
//前序遍历
//前序--递归
void PreOrderTra(PNode root) {
if (root != NULL) {
printf("%d\t", root->keyValue);
PreOrderTra(root->leftChild);
PreOrderTra(root->rightChild);
}
}
//前序--非递归
void PreOrderTra2(PNode root) {
if (!root) {
printf("树为空!\n");
}
stack<PNode> myStack;
while (root || !myStack.empty()) {
while (root)
{
myStack.push(root);
printf("%d\t", root->keyValue);
root = root->leftChild;
}
root = myStack.top();
myStack.pop();
root = root->rightChild;
}
printf("\n");
}
//后序遍历
//后序--递归
void PostOrderTra(PNode root) {
if (root) {
PostOrderTra(root->leftChild);
PostOrderTra(root->rightChild);
printf("%d\t", root->keyValue);
}
}
//后序--非递归
void PostOrderTra2(PNode root) {
int flag[30]; //用一个标记,标记右子树是否访问过
stack<PNode> myStack;
if (!root) {
printf("树为空!\n");
return;
}
while (root !=NULL ) { //首先将所有的左子树入栈
myStack.push(root);
flag[myStack.size()] = 0;
root = root->leftChild;
}
while (!myStack.empty()) {
root = myStack.top();
if (root->rightChild&&flag[myStack.size()] == 0) { //如果是第一次访问,则还不能输出,需要找到其右子树,将右子树入栈
flag[myStack.size()] = 1;
root = root->rightChild;
while (root)
{
myStack.push(root);
flag[myStack.size()] = 0;
root = root->leftChild;
}
}
root = myStack.top(); //第二次出栈,可以输出了
printf("%d\t", root->keyValue);
myStack.pop();
}
printf("\n");
}
//按层次遍历
//辅助函数,求树的最大深度
int getDeep(PNode root) {
if (!root) {
return 0;
}
int leftDeep = getDeep(root->leftChild) + 1;
int rightDeep = getDeep(root->rightChild) + 1;
return leftDeep > rightDeep ? leftDeep : rightDeep;
}
//输出指定的层,将根节点视为0层
int LevelOrderTra(PNode root,int level) {
if (!root || level < 0) {
printf("%s\t", "NULL");
return 0;
}
if (level == 0) {
printf("%d\t", root->keyValue);
return 1;
}
return LevelOrderTra(root->leftChild, level - 1) + LevelOrderTra(root->rightChild, level - 1);
}
//从根节点开始打印出所有层
void printByLevel(PNode root, int deep) {
for (int i = 0; i < deep; i++) {
LevelOrderTra(root, i);
}
printf("\n");
}
//法2,利用队列,实现安层次遍历
void printByLevel2(PNode root) {
if (!root) {
printf("树为空!\n");
}
queue<PNode> myQueue;
myQueue.push(root);
while (!myQueue.empty()) {
root = myQueue.front();
myQueue.pop();
printf("%d\t", root->keyValue);
if (root->leftChild)myQueue.push(root->leftChild);
if (root->rightChild) myQueue.push(root->rightChild);
}
}
/*=====================查找===================*/
int SearchTree(PNode root, dataType key) {
if (root->keyValue == key) {
return 1;
}
else if (key > root->keyValue && root->rightChild) {
return SearchTree(root->rightChild, key);
}
else if(key < root->keyValue && root->leftChild) {
return SearchTree(root->leftChild, key);
}
else {
return 0;
}
}
/*=======================删除==================*/
bool delNode(PNode &root, dataType key,bool &shorter) {
if (root == NULL) {
return false;
}
else if (key == root->keyValue) {
PNode tmp = NULL;
if (root->leftChild == NULL) {
tmp = root;
root = root->rightChild;
delete tmp;
shorter = true;
}
else if (root->rightChild == NULL) {
tmp = root;
root = root->leftChild;
delete tmp;
shorter = true;
}
else {
tmp = root->leftChild;
while (tmp->rightChild) {
tmp = tmp->rightChild;
}
root->keyValue = tmp->keyValue;
delNode(root->leftChild, tmp->keyValue, shorter);
}
}
else if (key < root->keyValue) {
if (!delNode(root->leftChild, key, shorter)) {
return false;
}
if (shorter) {
switch (root->BalanceFactor)
{
case LH:
root->BalanceFactor = EH;
shorter = true;
break;
case RH:
rightBalance(&root);
if (root->rightChild->BalanceFactor == EH) {
shorter = false;
}
else {
shorter = true;
}
break;
case EH:
root->BalanceFactor = RH;
shorter = false;
break;
}
}
}
else {
if (!delNode(root->rightChild, key, shorter)) {
return false;
}
if (shorter) {
switch (root->BalanceFactor)
{
case LH:
leftBalance(&root);
if (root->leftChild->BalanceFactor == EH) {
shorter = false;
}
else {
shorter = true;
}
break;
case EH:
root->BalanceFactor = LH;
shorter = false;
break;
case RH:
root->BalanceFactor = EH;
shorter = true;
break;
}
}
}
return true;
}
//void delNode2(PNode &root, dataType key) {
// if (!root) {
// printf("树为空!\n");
// return;
// }
// else if (!SearchTree(root, key)) {
// printf("树中不存在值为%d的节点\n", key);
// }else{
// PNode current = root;
// while (current->keyValue != key) {
// if (key < current->keyValue) current = current->leftChild;
// else current = current->rightChild;
// }
// if (current->leftChild && current->rightChild) {
// PNode minNode = current->rightChild;
// while (minNode) {
// minNode = minNode->leftChild;
// }
// current->keyValue = minNode->keyValue;
// PNode tmp = minNode;
// minNode = minNode->rightChild;
// delete tmp;
// }
// else if (current->leftChild || current->rightChild) {
// PNode tmp=current;
// current = current->leftChild ? current->leftChild : current->rightChild;
// delete tmp;
// }
// else {
// PNode tmp=current;
// current =NULL;
// delete tmp;
// }
// }
//}
int main()
{
int i, dataArr[] = { 1,23,45,34,98,9,4,35,23,36,37,90,85,80 };
PNode treeRoot = NULL;
bool heigher;
for (i = 0; i < 14; i++) {
InsertKeyValue(&treeRoot, dataArr[i],&heigher);
/*printfTree(treeRoot);
printf("\n\n");*/
}
/*printf("中序遍历是:");
InorderTra(treeRoot);
printf("\n");
InorderTra2(treeRoot);*/
/*printf("前序遍历是:");
PreOrderTra(treeRoot);
printf("\n");
PreOrderTra2(treeRoot);*/
/*printf("后序遍历是:");
PostOrderTra(treeRoot);
printf("\n");
PostOrderTra2(treeRoot);*/
/*printf("deep:%d\n", getDeep(treeRoot));*/
printf("层次遍历是:");
printByLevel(treeRoot, getDeep(treeRoot));
printf("\n");
/*printByLevel2(treeRoot);*/
//测试查找
/*while (true)
{
printf("请输入要查找的值:");
int key;
scanf("%d", &key);
printf("\n查找结果:%d\n", SearchTree(treeRoot, key));
}*/
//测试删除
while (true)
{
printf("请输入要删除的值:");
int key;
scanf("%d", &key);
bool shoter = false;
delNode(treeRoot, key,shoter);
/*delNode2(treeRoot, key);*/
printByLevel(treeRoot,4);
}
return 0;
}