C/C++實現平衡二叉樹的插入、刪除、查詢和各種遍歷
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;
}