实验目的
通过本次实验,掌握二叉树递归处理算法,并会分析该算法的时间复杂度。
实验内容
删除二叉树的子树:假设二叉树中的结点均不相等,采用二叉链存储,设计递归算法删除根结点值为x的子树。
实验过程
1.算法设计
1.首先递归创建一颗二叉树
根据输入的节点值创建二叉树根据用户输入的节点值(#表示空节点),使用递归的方式创建二叉树。
2.查找要删除的子树的根节点
输入要删除的子树的根节点的值,程序在二叉树中查找值为该值的节点,并返回该节点的指针。
3.递归删除子树
对于当前节点,依次递归删除其左子树和右子树中值为子树根节点值的子树。如果当前节点为空或者当前节点的值不等于子树根节点的值,则直接返回当前节点的指针。如果当前节点的左子树或右子树中存在值为子树根节点的节点,则将该节点的左子树或右子树置为空,并释放该节点的空间。
4.输出删除子树后的二叉树
使用中序遍历的方式遍历二叉树,输出删除子树后的节点值序列。
5.输出删除成功,结束程序
程序清单
#include <stdio.h> #include <stdlib.h> #define TYPE char struct biTree { TYPE data; struct biTree *lchild; struct biTree *rchild; }; /** * 释放节点T函数 * @param T */ void del(struct biTree *T) { if (T) { if (T->lchild)del(T->lchild); if (T->rchild)del(T->rchild); free(T); } } /** 这里设置一个父结点指针 因为free只会释放所在结点里面的内容 并不会置空 **/ void delXsub(struct biTree *T, int x) { struct biTree *p = T; if (p->lchild && p->lchild->data == x) { del(p->lchild); p->lchild = NULL; } if (p->rchild && p->rchild->data == x) { del(p->rchild); p->rchild = NULL; } if (p->lchild)delXsub(p->lchild, x); if (p->rchild)delXsub(p->rchild, x); } /** * 递归先序遍历创建二叉树,返回二叉树 * @param T * @return */ struct biTree *create(struct biTree *T) { TYPE data;//当前结点 printf("data="); scanf("%c", &data); getchar(); if (data != '#') { T = (struct biTree *) malloc(sizeof(struct biTree *)); T->data = data; T->lchild = NULL; T->rchild = NULL; T->lchild = create(T->lchild); T->rchild = create(T->rchild); } return T; } /** * 中序遍历二叉树 * @param T */ void inOrder(struct biTree *T) { if (T != NULL) { inOrder(T->lchild); printf("%c", T->data); inOrder(T->rchild); } } int main() { char x; struct biTree *T = (struct biTree *) malloc(sizeof(struct biTree)); //创建一棵二叉树 T = create(T); printf("中序遍历结果为:\n"); inOrder(T); //换行 printf("\n"); printf("请输入您要删除的x的值:x="); scanf("%c", &x); printf("删除后中序遍历结果为:\n"); if (T->data == x) { //调用函数删除 del(T); } else { //再次查找 delXsub(T, x); } inOrder(T); printf("删除结点及其子树成功!"); return true; }
复杂度分析
(1)时间复杂度
O(n)
(2)空间复杂度
O(log2n)
运行结果
结果一
结果二: