二叉树基本操作的C语言实现
- 判断二叉树是否为空
- 查找数据
- 插入数据
- 删除数据
- 查找父亲
- 查找左儿子
- 查找右儿子
- 查找节点深度
- 二叉树深度
- 判断叶子结点
- 查找堂兄弟
- 清空二叉树
- 打印二叉树
- 前序遍历
- 中序遍历
- 后序遍历
- 转换成完全二叉树
- 判断是否为子树
- 判断是否为对称树
#include
#include
typedef int DataType;
typedef struct Node {
DataType data;
struct Node *LChild;
struct Node *RChild;
}BTNode, *BTree;
void initial(BTree *T);
int isEmpty(BTree T);
BTNode *search(BTree T,DataType d);
BTNode *insert(BTree *T,DataType d);
BTNode *remov(BTree*T,DataType d);
DataType parent(BTree T,DataType d);
DataType leftSon(BTree T,DataType d);
DataType rightSon(BTree T,DataType d);
int depth(BTree T,DataType d);
int height(BTree T);
int isLeaf(BTree T,DataType d);
int leafCount(BTree T);
int allCousins(BTree T,DataType d);
void clearTree(BTree *T);
void printTree(BTree T);
void preorderTraversal(BTree T);
void inorderTraversal(BTree T);
void postorderTraversal(BTree T);
BTree toCompletTree(BTree T);
int isSubtree(BTree S, BTree T);
int isSymmetric(BTree T);
int main() {
printf("****************** 有序二叉树相关操作 *****************\n");
printf("1. 判断二叉树是否为空\n");
printf("2. 查找数据\n");
printf("3. 插入数据\n");
printf("4. 删除数据\n");
printf("5. 查找父亲\n");
printf("6. 查找左儿子\n");
printf("7. 查找右儿子\n");
printf("8. 查找节点深度\n");
printf("9. 二叉树深度\n");
printf("10. 判断叶子结点\n");
printf("11. 查找堂兄弟\n");
printf("12. 清空二叉树\n");
printf("13. 打印二叉树\n");
printf("14. 前序遍历\n");
printf("15. 中序遍历\n");
printf("16. 后序遍历\n");
printf("17. 转换成完全二叉树\n");
printf("18. 判断是否为子树\n");
printf("19. 判断是否为对称树\n");
printf("0. 退出\n");
printf("****************************************************\n\n");
BTree tree;
initial(&tree);
while(1) {
printf("请输入您的选择:");
int opt;
scanf("%d",&opt);
if(opt == 1) {
printf(isEmpty(tree) ? "二叉树为空\n" : "二叉树非空\n");
printf("\n");
}else if(opt == 2) {
int d;
printf("请输入待查找数据:");
scanf("%d",&d);
BTree res = search(tree, d);
if(res == NULL) printf("无此数据!\n");
else printf("查找成功, 元素存在于二叉树!\n");
printf("\n");
}else if(opt == 3) {
int d;
printf("请输入待插入数据:");
scanf("%d",&d);
BTree res = insert(&tree, d);
printf("插入 %d 成功!\n",res -> data);
printf("\n");
}else if(opt == 4) {
int d;
printf("请输入待删除数据:");
scanf("%d",&d);
BTree res = remov(&tree, d);
if(res != NULL) printf("删除 %d 成功!\n",res -> data);
printf("\n");
}else if(opt == 5) {
int d;
printf("请输入待查询节点数据:");
scanf("%d",&d);
int k = parent(tree, d);
if(k != -1) printf("%d 节点父亲节点数据为 %d!\n",d, k);
else printf("无父亲!\n");
printf("\n");
}else if(opt == 6) {
int d;
printf("请输入待查询节点数据:");
scanf("%d",&d);
int k = leftSon(tree, d);
if(k != -1) printf("%d 节点左儿子节点数据为 %d!\n",d, k);
else printf("无左儿子!\n");
printf("\n");
}else if(opt == 7) {
int d;
printf("请输入待查询节点数据:");
scanf("%d",&d);
int k = rightSon(tree, d);
if(k != -1) printf("%d 节点右儿子节点数据为 %d!\n",d, k);
else printf("无右儿子!\n");
printf("\n");
}else if(opt == 8) {
int d;
printf("请输入待查询节点数据:");
scanf("%d",&d);
int k = depth(tree, d);
if(k != -1) printf("%d 节点深度为 %d!\n",d, k);
else printf("无此节点!\n");
printf("\n");
}else if(opt == 9) {
printf("二叉树深度为 %d!\n", height(tree));
printf("\n");
}else if(opt == 10) {
int d;
printf("请输入待判断节点数据:");
scanf("%d",&d);
int k = isLeaf(tree, d);
if(k != -1) printf(k ? "该节点是叶子结点\n" : "该节点不是叶子结点\n");
printf("\n");
}else if(opt == 11) {
int d;
printf("请输入待查找节点数据:");
scanf("%d",&d);
printf("%d 节点所有堂兄弟为: ",d);
int k = allCousins(tree, d);
printf("\n该节点有 %d 个堂兄弟!\n\n",k);
}else if(opt == 12) {
clearTree(&tree);
printf("\n");
}else if(opt == 13) {
printTree(tree);
printf("\n\n");
}else if(opt == 14) {
printf("前序遍历结果:\n");
preorderTraversal(tree);
printf("\n\n");
}else if(opt == 15) {
printf("中序遍历结果:\n");
inorderTraversal(tree);
printf("\n\n");
}else if(opt == 16) {
printf("后序遍历结果:\n");
postorderTraversal(tree);
printf("\n\n");
}else if(opt == 17) {
tree = toCompletTree(tree);
printf("成功转化成完全二叉树\n");
printf("\n");
}else if(opt == 18) {
int a,b;
printf("请输入两个节点数据:");
scanf("%d %d",&a,&b);
int k = isSubtree(search(tree,a), search(tree,b));
printf(k ? "是子树\n" : "不是子树\n");
printf("\n");
}else if(opt == 19) {
int k = isSymmetric(tree);
printf(k ? "是对称树\n" : "不是对称树\n");
printf("\n");
}else if(opt == 0) {
break;
}else{
printf("输入有误!\n");
}
}
}
void initial(BTree *T)
{
*T = NULL;
}
int isEmpty(BTree T)
{
return T == NULL ? 1 : 0;
}
BTNode *search(BTree T,DataType d)
{
if(T == NULL) return NULL;
if(T -> data == d) return T;
else if(d < T -> data) return search(T -> LChild, d);
else return search(T -> RChild, d);
}
BTNode *insert(BTree *T,DataType d)
{
BTree fa = NULL, cur = *T;
int exist = 0;
if(*T == NULL) {
*T = (BTNode *)malloc(sizeof(BTNode));
(*T) -> LChild = (*T) -> RChild = NULL;
(*T) -> data = d;
return *T;
}else{
while(cur != NULL) {
if(d < cur -> data) {
fa = cur;
cur = cur -> LChild;
}else if(d > cur -> data){
fa = cur;
cur = cur -> RChild;
}else{
exist = 1;
break;
}
}
}
if(exist == 1) return cur;
if(d > fa -> data) {
fa -> RChild = (BTNode *)malloc(sizeof(BTNode));
fa -> RChild -> data = d;
fa -> RChild -> LChild = fa -> RChild -> RChild = NULL;
return fa -> RChild;
}else{
fa -> LChild = (BTNode *)malloc(sizeof(BTNode));
fa -> LChild -> data = d;
fa -> LChild -> LChild = fa -> LChild -> RChild = NULL;
return fa -> LChild;
}
}
BTree parent_point(BTree T,DataType d)
{
BTree fa = NULL, cur = T;
while(cur != NULL && cur -> data != d) {
if(d > cur -> data) {
fa = cur;
cur = cur -> RChild;
}else{
fa = cur;
cur = cur -> LChild;
}
}
if(fa == NULL) return NULL;
else return fa;
}
BTNode *remov(BTree *T,DataType d)
{
BTNode *parent = parent_point(*T, d);
BTNode *node = search(*T, d);
if(node == NULL)
printf("没有待删节点\n");
else
{
if(node->LChild == NULL && node->RChild == NULL)
{
if(parent == NULL)
*T = NULL;
else
{
if(node == parent->LChild)
parent->LChild = NULL;
else
parent->RChild = NULL;
}
}
else if(node->RChild == NULL)
{
if(parent == NULL)
*T = node->LChild;
else
{
if(node == parent->LChild)
parent->LChild = node->LChild;
else
parent->RChild = node->LChild;
}
}
else if(node->LChild == NULL)
{
if(parent == NULL)
*T = node->RChild;
else
{
if(node == parent->LChild)
parent->LChild = node->RChild;
else
parent->RChild = node->RChild;
}
}
else
{
BTNode *new_node = node->RChild;
BTNode *new_node_parent = NULL;
while(new_node->LChild != NULL)
{
new_node_parent = new_node;
new_node = new_node->LChild;
}
new_node->LChild = node->LChild;
if(new_node != node->RChild)
new_node->RChild = node->RChild;
if(parent == NULL)
*T = new_node;
else
{
if(node == parent->LChild)
parent->LChild = new_node;
else
parent->RChild = new_node;
}
if(new_node_parent != NULL)
new_node_parent->LChild = NULL;
}
}
return node;
}
DataType parent(BTree T,DataType d)
{
BTree fa = NULL, cur = T;
while(cur != NULL && cur -> data != d) {
if(d > cur -> data) {
fa = cur;
cur = cur -> RChild;
}else{
fa = cur;
cur = cur -> LChild;
}
}
if(fa == NULL) return -1;
else return fa -> data;
}
DataType leftSon(BTree T,DataType d)
{
BTNode *pos = search(T, d);
if(pos == NULL) return -1;
else return pos -> LChild == NULL ? -1: pos -> LChild -> data;
}
DataType rightSon(BTree T,DataType d)
{
BTNode *pos = search(T, d);
if(pos == NULL) return -1;
else return pos -> RChild == NULL ? -1: pos -> RChild -> data;
}
int depth(BTree T, DataType d)
{
if(T == NULL) return 0;
if(d > T -> data) {
return 1 + depth(T -> RChild, d);
}else if(d == T -> data) {
return 1;
}else{
return 1 + depth(T -> LChild, d);
}
}
int height(BTree T)
{
if(T == NULL) return 0;
if(T -> LChild == NULL && T -> RChild == NULL) return 1;
int Ld = height(T -> LChild), Rd = height(T -> RChild);
return 1 + (Ld > Rd ? Ld : Rd);
}
int isLeaf(BTree T,DataType d)
{
BTNode *pos = search(T, d);
return (pos -> LChild == NULL && pos -> RChild == NULL) ? 1 : 0;
}
int leafCount(BTree T)
{
if(T == NULL) return 0;
if(T -> LChild == NULL && T -> RChild == NULL) return 1;
return leafCount(T -> LChild) + leafCount(T -> RChild);
}
int print_cousin(BTree T, int fad,int depd, int fa, int h) {
if(h == depd && fa != fad) {
printf("%d ",T -> data);
return 1;
}
int L = 0, R = 0;
if(T -> LChild != NULL) L = print_cousin(T -> LChild, fad, depd, T -> data, h+1);
if(T -> RChild != NULL) R = print_cousin(T -> RChild, fad, depd, T -> data, h+1);
return L + R;
}
int allCousins(BTree T,DataType d)
{
if(T == NULL) return 0;
int depd = depth(T, d);
int fad = parent(T, d);
return print_cousin(T, fad, depd, -1, 1);
}
void clearTree(BTree *T)
{
if(T == NULL) return;
clearTree(&((*T) -> LChild));
clearTree(&((*T) -> RChild));
free(*T);
*T = NULL;
}
void mid_visit(BTree T, int d) {
int i;
if(T == NULL) return;
if(T -> RChild != NULL) mid_visit(T -> RChild, d+1);
for(i = 1; i <= d; i++) printf(" ");
printf("%d", T -> data);
if(T -> LChild != NULL) mid_visit(T -> LChild, d+1);
}
void printTree(BTree T)
{
mid_visit(T, 1);
}
void preorderTraversal(BTree T)
{
if(T == NULL) return;
printf("%d ",T -> data);
if(T -> LChild != NULL) preorderTraversal(T -> LChild);
if(T -> RChild != NULL) preorderTraversal(T -> RChild);
}
void inorderTraversal(BTree T)
{
if(T == NULL) return;
if(T -> LChild != NULL) inorderTraversal(T -> LChild);
printf("%d ",T -> data);
if(T -> RChild != NULL) inorderTraversal(T -> RChild);
}
void postorderTraversal(BTree T)
{
if(T == NULL) return;
if(T -> LChild != NULL) postorderTraversal(T -> LChild);
if(T -> RChild != NULL) postorderTraversal(T -> RChild);
printf("%d ",T -> data);
}
void mid(BTree T, int *index, BTNode arr[]) {
if(T == NULL) return;
if(T -> LChild != NULL) mid(T -> LChild, index, arr);
*index = *index + 1;
arr[*index] = *T;
if(T -> RChild != NULL) mid(T -> RChild, index, arr);
}
int num_node(BTree T) {
if(T == NULL) return 0;
return 1 + num_node(T -> LChild) + num_node(T -> RChild);
}
void fill(BTree T, DataType all[], int *index) {
if(T -> LChild != NULL) fill(T -> LChild, all, index);
*index = *index + 1;
T -> data = all[*index];
if(T -> RChild != NULL) fill(T -> RChild, all, index);
}
BTree toCompletTree(BTree T)
{
int n = num_node(T), index = 0, i;
BTNode * arr = (BTNode *) malloc((n+1) * sizeof(BTNode));
DataType *v = (DataType *)malloc((n+1) * sizeof(DataType));
mid(T, &index, arr);
for(int i=1;i<=index;i++) v[i] = arr[i].data;
for(i = 1; i <= n; i++) {
if(2 * i <= n) arr[i].LChild = &arr[2*i];
else arr[i].LChild = NULL;
if(2 * i + 1 <= n) arr[i].RChild = &arr[2*i+1];
else arr[i].RChild = NULL;
}
index = 0;
fill(arr + 1, v, &index);
return arr + 1;
}
int is_same(BTree S, BTree T)
{
if((S == NULL && T != NULL) || (S != NULL && T == NULL)) return 0;
if(S == NULL && T == NULL) return 1;
if(S -> data != T -> data) return 0;
return is_same(S -> LChild, T -> LChild) && is_same(S -> RChild, T -> RChild) ? 1 : 0;
}
int isSubtree(BTree S, BTree T)
{
return (is_same(S, T->LChild) || is_same(S, T -> RChild)) ? 1 : 0;
}
int check(BTree S, BTree T)
{
if(S == NULL && T == NULL) return 1;
if(S == NULL || T == NULL) return 0;
int L = check(S -> LChild, T-> RChild), R = check(S -> RChild, T -> LChild);
return (L == 1 && R == 1) ? 1 : 0;
}
int isSymmetric(BTree T)
{
if(T == NULL) return 1;
return check(T -> LChild, T -> RChild);
}