4.10
#include<stdio.h>
#include<malloc.h>
#include<stdlib.h>
/* 二叉查找树 p80
1.假设二叉树中个元素互异
2.都是整数
*/
typedef struct BiTreeNode{
int data;
struct BiTreeNode* pLeft; //左节点
struct BiTreeNode* pRight; //右节点
}SearchTree,*PtrSearchTree;
typedef PtrSearchTree PtrTreeNode;
typedef SearchTree TreeNode;
/*返回类型为PtrTreeNode表示返回树的一个节点,返回类型为PtrSearchTree表示返回树的根节点*/
void makeEmpty(PtrSearchTree pTree);
PtrSearchTree initTree(void); //初始化一棵树,图4-15(左)
PtrTreeNode find(int val, PtrSearchTree pTree); //在树中找到值为val的元素的节点
PtrTreeNode findMinNode(PtrSearchTree pTree); //寻找树的最小值的节点
PtrTreeNode findMaxNode(PtrSearchTree pTree); //寻找树的最大值的节点
PtrSearchTree Insert(int val, PtrSearchTree pTree); // 插入操作,返回插入后的新树的根
//若val在树内, 则什么也不做
PtrTreeNode newTreeNode(int val); //创建一个data=val,孩子均为NULL的新节点
PtrSearchTree Delete(int val, PtrSearchTree pTree); //删除val,返回删除后的新树的根
void inorderTraversal(PtrSearchTree pTree); //中序遍历
void showTree(PtrSearchTree pTree); //输出树的元素(中序遍历)
int main(void) {
//初始树可以先pTree=NULL;再使用Insert
PtrSearchTree pTree = initTree();
showTree(pTree);
pTree = Insert(6, pTree); //p80,图4-21(右)
showTree(pTree);
pTree = Delete(3, pTree);
showTree(pTree);
return 0;
}
void makeEmpty(PtrSearchTree pTree) {//清空一棵树
if(pTree != NULL) {
makeEmpty(pTree->pLeft);
makeEmpty(pTree->pRight);
free(pTree);
}
return;
}
PtrSearchTree initTree(void) {//初始化一棵树,图4-15(左)
PtrSearchTree root = newTreeNode(6);//根节点
PtrTreeNode p1 = newTreeNode(2);
PtrTreeNode p2 = newTreeNode(8);
PtrTreeNode p3 = newTreeNode(1);
PtrTreeNode p4 = newTreeNode(4);
PtrTreeNode p5 = newTreeNode(3);
root->pLeft = p1;
root->pRight = p2;
p1->pLeft = p3;
p1->pRight = p4;
p4->pLeft = p5;
return root;
}
PtrTreeNode find(int val, PtrSearchTree pTree) {//在树中找到值为val的元素的节点
if (pTree == NULL)
return NULL;
if (val > pTree->data)
return find(val, pTree->pRight);
if (val < pTree->data)
return find(val, pTree->pLeft);
else
return pTree;
}
PtrTreeNode findMinNode(PtrSearchTree pTree) {//寻找数的最小值的节点
if (pTree == NULL)
return NULL;
if (pTree->pLeft != NULL)
return findMinNode(pTree->pLeft);
else
return pTree;
}
PtrTreeNode findMaxNode(PtrSearchTree pTree) {//寻找树的最大值的节点
if (pTree == NULL)
return NULL;
if (pTree->pRight != NULL)
return findMaxNode(pTree->pRight);
else
return pTree;
}
PtrSearchTree Insert(int val, PtrSearchTree pTree) {//插入操作,若val在树内,则什么也不做
if (pTree == NULL)
pTree = newTreeNode(val);
if (val > pTree->data)
pTree->pRight = Insert(val, pTree->pRight);
if (val < pTree->data)
pTree->pLeft = Insert(val, pTree->pLeft);
return pTree;
}
PtrTreeNode newTreeNode(int val) {//创建一个data=val,孩子均为NULL的新节点
PtrSearchTree pTree = (PtrSearchTree)malloc(sizeof(TreeNode));
if (pTree == NULL) {
printf("pTree分配内存失败!\n");
}
else {
pTree->data = val;
pTree->pLeft = NULL;
pTree->pRight = NULL;
}
return pTree;
}
PtrSearchTree Delete(int val, PtrSearchTree pTree) {//删除val,返回删除后的新树的根(全看成在根节点(第一次输入)进行操作)
if (pTree == NULL) {
printf("树中没有要删除的元素!\n");
return NULL;
}
else if (val > pTree->data)
pTree->pRight = Delete(val, pTree->pRight);//到右子树中删除,返回右子树的根
else if (val < pTree->data)
pTree->pLeft = Delete(val, pTree->pLeft);到左子树中删除,返回左子树的根
else {//val == pTree->data,看有几个子节点
if (pTree->pLeft != NULL && pTree->pRight != NULL) {//两个子节点
//删除方法:我变成你(右子树中的最小值),再杀了你,等于我杀了我自己
PtrTreeNode pTemp = findMinNode(pTree->pRight);
pTree->data = pTemp->data;
pTree->pRight = Delete(pTemp->data, pTree->pRight);
}
else {//一个或0个节点
//删除方法:直接删除
PtrTreeNode pTemp = pTree;
if (pTree->pLeft == NULL)
pTree = pTree->pRight;
else if (pTree->pRight == NULL)
pTree = pTree->pLeft;
free(pTemp);
}
}
return pTree;
}
void inorderTraversal(PtrSearchTree pTree) {//中序遍历
if (pTree == NULL) {
printf("树为空!\n");
exit(-1);
}
if (pTree->pLeft != NULL)
inorderTraversal(pTree->pLeft);
printf("%d ", pTree->data);
if (pTree->pRight != NULL)
inorderTraversal(pTree->pRight);
return;
}
void showTree(PtrSearchTree pTree) {
if (pTree == NULL) {
printf("树为空!\n");
return;
}
printf("中序遍历该树:");
inorderTraversal(pTree);
printf("\n");
}