插入代码(递归)
BTNode* BTInsert(BTNode* root, BTDataType a)
{
if (root == NULL)
{
BTNode*newnode=(BTNode*)malloc(sizeof(BTNode));
assert(newnode);
newnode->Data = a;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
else if (a < root->Data)
{
root->left = BTInsert(root->left, a);
}
else
{
root->right = BTInsert(root->right , a);
}
return root;
}
我们可以通过假设只在根节点root插入数据(3种情况)
1.root为空
2.插入值小于root的值
3.插入值大于root的值
我们可以使用递归,从而完成插入。
查找代码(递归)
BTNode* BTSearch(BTNode* root, BTDataType a)
{
if (root == NULL || root->Data == a)
{
return root;
}
else if (a < root->Data)
{
return BTSearch(root->left, a);
}
else
{
return BTSearch(root->right, a);
}
}
我们可以通过假设只在根节点root插入数据(3种情况)
1.root为空或root的值等于要查找的值
2.查找的值小于root的值
3.查找的值大于root的值
我们可以使用递归,从而完成查找。
查找最大值
BTNode* BTFindMax(BTNode* root)
{
assert(root);
if (root->right == NULL)
{
return root;
}
else
{
while (root->right)
{
root = root->right;
}
return root;
}
}
根据搜索二叉树的性质最大值一定在搜索二叉树的最右端,因此我们可以沿着根结点不断往下找,直到找到右结点为空。
删除
删除分为4种情况
1.要删除的结点左右孩子都为空
直接删除
2.要删除的结点左孩子为空,右孩子不为空
(1).判断要删除的结点在父节点的左孩子还是右孩子
(2).将要删除的结点右孩子连接到父节点
(3).释放结点
3.要删除的结点左孩子不为空,右孩子为空
(1).判断要删除的结点在父节点的左孩子还是右孩子
(2).将要删除的结点左孩子连接到父节点
(3).释放结点
4.要删除的结点左右孩子都不为空(找到要删除结点左孩子为根的最大值)
1.找到要删除结点左孩子为根的最大值的结点为swap
2.找到swap的父节点
3.将要删除的结点的值替换为swap的值
4.删除结点swap
void BTDelete(BTNode* root, BTDataType a)
{
assert(root);
BTNode* aim = BTSearch(root, a);//aim为删除对象
if (aim == NULL)
{
printf("不存在此数,删除失败\n");
exit(-1);
}
BTNode* aimleft = aim->left;
BTNode* aimright = aim->right;
BTNode* parent = NULL;
//左右孩子都为空
if (aimleft == NULL && aimright == NULL)
{
parent = BTChildParent(root, a);
if (a < parent->Data)
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
free(aim);
aim = NULL;
}
//只有左孩子节点
else if (aimleft != NULL && aimright == NULL)
{
parent = BTChildParent(root, a);
if (parent->Data < aim->Data)
{
parent->right = aim->left;
}
else
{
parent->left = aim->left;
}
free(aim);
aim = NULL;
}
//只有右孩子
else if (aimleft == NULL && aimright != NULL)
{
parent = BTChildParent(root, a);
if (parent->Data < aim->Data)
{
parent->right = aim->right;
}
else
{
parent->left = aim->right;
}
free(aim);
aim = NULL;
}
//既有左孩子又有右孩子
else
{
BTNode* swap = BTFindMax(aim->left);//swap用于aim赋值
parent = BTChildParent(root, swap->Data);//parent为swap的父亲
aim->Data = swap->Data;
//swap左右孩子都为空(既有左孩子又有右孩子)
if (swap->left == NULL && swap->right == NULL)
{
if (parent->Data < swap->Data)
{
parent->right = NULL;
}
else
{
parent->left = NULL;
}
}
//swap只有左孩子节点(既有左孩子又有右孩子)
else if (swap->left != NULL && swap->right == NULL)
{
if (parent->Data < swap->Data)
{
parent->right = swap->left;
}
else
{
parent->left = swap->left;
}
free(swap);
swap = NULL;
}
//swap只有右孩子节点(既有左孩子又有右孩子)
else if (swap->left == NULL && swap->right != NULL)
{
if (parent->Data < swap->Data)
{
parent->right = swap->right;
}
else
{
parent->left = swap->right;
}
free(swap);
swap = NULL;
}
}
}
源代码
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
typedef int BTDataType;
typedef struct BinaryTreeNode
{
BTDataType Data;
struct BinaryTreeNode* left;
struct BinaryTreeNode* right;
}BTNode;
//前序(递归)
void PrevOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
printf("%d ", root->Data);
PrevOrder(root->left);
PrevOrder(root->right);
}
//中序(递归)
void InOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
InOrder(root->left);
printf("%d ", root->Data);
InOrder(root->right);
}
//后序(递归)
void PostOrder(BTNode* root)
{
if (root == NULL)
{
return;
}
PostOrder(root->left);
PostOrder(root->right);
printf("%d ", root->Data);
}
//层序(队列)
void LevelOrder(BTNode* root)
{
assert(root);
int head = 0;
int tail = 0;
BTNode* tem;
BTNode* BTarr[1000];
tail++;
BTarr[tail] = root;
while (tail != head)
{
head++;
tem = BTarr[head];
printf("%d ", tem->Data);
if (tem->left != NULL)
{
tail++;
BTarr[tail] = tem->left;
}
if (tem->right != NULL)
{
tail++;
BTarr[tail] = tem->right;
}
}
}
//插入(递归)
BTNode* BTInsert(BTNode* root, BTDataType a)
{
if (root == NULL)
{
BTNode* newnode = (BTNode*)malloc(sizeof(BTNode));
assert(newnode);
newnode->Data = a;
newnode->left = NULL;
newnode->right = NULL;
return newnode;
}
else if (a < root->Data)
{
root->left = BTInsert(root->left, a);
}
else
{
root->right = BTInsert(root->right, a);
}
return root;
}
//查找(递归)
BTNode* BTSearch(BTNode* root, BTDataType a)
{
if (root == NULL || root->Data == a)
{
return root;
}
else if (a < root->Data)
{
return BTSearch(root->left, a);
}
else
{
return BTSearch(root->right, a);
}
}
//找双亲
BTNode* BTChildParent(BTNode* root, BTDataType a)
{
assert(root);
if (root->right)
{
if (root->right->Data == a)
{
return root;
}
}
if (root->left)
{
if (root->left->Data == a)
{
return root;
}
}
if (a < root->Data)
{
return BTChildParent(root->left, a);
}
else
{
return BTChildParent(root->right, a);
}
}
//找最搜索二叉树的最大值并返回地址
BTNode* BTFindMax(BTNode* root)
{
assert(root);
if (root->right == NULL)
{
return root;
}
else
{
while (root->right)
{
root = root->right;
}
return root;
}
}
void BTDelete(BTNode* root, BTDataType a)
{
assert(root);
BTNode* aim = BTSearch(root, a);//aim为删除对象
if (aim == NULL)
{
printf("不存在此数,删除失败\n");
exit(-1);
}
BTNode* aimleft = aim->left;
BTNode* aimright = aim->right;
BTNode* parent = NULL;
//左右孩子都为空
if (aimleft == NULL && aimright == NULL)
{
parent = BTChildParent(root, a);
if (a < parent->Data)
{
parent->left = NULL;
}
else
{
parent->right = NULL;
}
free(aim);
aim = NULL;
}
//只有左孩子节点
else if (aimleft != NULL && aimright == NULL)
{
parent = BTChildParent(root, a);
if (parent->Data < aim->Data)
{
parent->right = aim->left;
}
else
{
parent->left = aim->left;
}
free(aim);
aim = NULL;
}
//只有右孩子
else if (aimleft == NULL && aimright != NULL)
{
parent = BTChildParent(root, a);
if (parent->Data < aim->Data)
{
parent->right = aim->right;
}
else
{
parent->left = aim->right;
}
free(aim);
aim = NULL;
}
//既有左孩子又有右孩子
else
{
BTNode* swap = BTFindMax(aim->left);//swap用于aim赋值
parent = BTChildParent(root, swap->Data);//parent为swap的父亲
aim->Data = swap->Data;
//swap左右孩子都为空(既有左孩子又有右孩子)
if (swap->left == NULL && swap->right == NULL)
{
if (parent->Data < swap->Data)
{
parent->right = NULL;
}
else
{
parent->left = NULL;
}
}
//swap只有左孩子节点(既有左孩子又有右孩子)
else if (swap->left != NULL && swap->right == NULL)
{
if (parent->Data < swap->Data)
{
parent->right = swap->left;
}
else
{
parent->left = swap->left;
}
free(swap);
swap = NULL;
}
//swap只有右孩子节点(既有左孩子又有右孩子)
else if (swap->left == NULL && swap->right != NULL)
{
if (parent->Data < swap->Data)
{
parent->right = swap->right;
}
else
{
parent->left = swap->right;
}
free(swap);
swap = NULL;
}
}
}
int main()
{
BTNode* root = NULL;
root = BTInsert(root, 25);
root = BTInsert(root, 20);
root = BTInsert(root, 36);
root = BTInsert(root, 10);
root = BTInsert(root, 22);
root = BTInsert(root, 30);
root = BTInsert(root, 40);
root = BTInsert(root, 5);
root = BTInsert(root, 12);
root = BTInsert(root, 28);
root = BTInsert(root, 38);
root = BTInsert(root, 48);
root = BTInsert(root, 1);
root = BTInsert(root, 8);
root = BTInsert(root, 15);
root = BTInsert(root, 45);
root = BTInsert(root, 50);
BTDelete(root,25);
InOrder(root);
printf("\n");
LevelOrder(root);
return 0;
}
搜索二叉树:
运行结果: