代码仅作纪念,作为对数据结构----树的一点小总结吧。不保证其权威性。也许有缺漏。算法大佬轻喷。
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define SIZE 50
typedef struct TNode{
char weight;
struct TNode *left,*right;
}BTnode,*BTree;
typedef struct STNode{
int weight;
struct STNode *left,*right;
}BSTnode,*BSTree;
BTree creatBT();
BSTree creatBST(BSTree &ST,int data[] ,int length);
int BSTnode_insert(BSTree &ST,int x);
int max(int a,int b);
void PreOrder(BTree &T);
void MiddleOrder(BTree &T);
void HouOrder(BTree &T);
int NumOfNode(BTree &T);
int HegihtOfTree(BTree &T);
int leafNum(BTree &T);
bool isAVLBt(BTree &T);
BSTnode* BST(BSTree &T,int key,BSTnode** parent,int &flag);
BSTnode* BST_parent(BSTree &T,BSTnode* child);
void DelBSTNode(BSTree &ST,int key,int &flag);
void PreOrderS(BSTree &T);
BSTnode* FirstOfMid(BSTree &T);
static BSTnode* parent=NULL;
static int flag=0;//若为0则表示parent->left=child,若为1则表示parent->right=childe,若为3则表示无孩子,即parent为NULL
int main(){
BTree BT;
BT=creatBT();
PreOrder(BT);
printf("\n");
MiddleOrder(BT);
printf("\n");
HouOrder(BT);
printf("\n");
printf("节点数:%d\n",NumOfNode(BT));
printf("树的深度:%d\n",HegihtOfTree(BT));
printf("叶子节点数目:%d\n",leafNum(BT));
printf("是否为avl:%d\n",isAVLBt(BT));
/*int data[10]={5,2,1,0,3,4,6,8,7,9};
BSTree T=NULL;
T=creatBST(T,data,10);
PreOrderS(T);
printf("\n");*/
/*if(!BST(T,0,&parent,flag)){
printf("不存在\n");
}
else{
printf("存在\n");
printf("找到了\n");
//BST(T,3,parent);
if(!parent){
printf("父节点为空\n");
printf("%d\n",flag);
}
else{
printf("父节点的值:%d\n",parent->weight);
printf("%d\n",flag);
}
}*/
/*DelBSTNode(T,8,flag);
PreOrderS(T);*/
return 0;
}
int max(int a,int b){
if(a>=b){
return a;
}
else{
return b;
}
}
//创建二叉树(先序构建)
BTree creatBT( )
{
BTree T;
char data;
scanf("%c",&data);
if(data==' '){
T=NULL;
}
else{
T=(BTree)malloc(sizeof(BTnode));
T->weight=data;
T->left=creatBT();
T->right=creatBT();
}
return T;
}
//先序遍历
void PreOrder(BTree &T){
if(T){
printf("%c",T->weight);
PreOrder(T->left);
PreOrder(T->right);
}
}
//先序遍历二叉查找树
void PreOrderS(BSTree &T){
if(T){
printf("%d",T->weight);
PreOrderS(T->left);
PreOrderS(T->right);
}
}
//中序遍历
void MiddleOrder(BTree &T){
if(T){
MiddleOrder(T->left);
printf("%c",T->weight);
MiddleOrder(T->right);
}
}
//后序遍历
void HouOrder(BTree &T){
if(T){
HouOrder(T->left);
HouOrder(T->right);
printf("%c",T->weight);
}
}
//统计树的节点数
int NumOfNode(BTree &T){
if(T==NULL){
return 0;
}
else{
return (NumOfNode(T->left)+NumOfNode(T->right)+1);
}
}
//求树的高度
int HegihtOfTree(BTree &T){
if(T==NULL){
return 0;
}
return max(HegihtOfTree(T->left),HegihtOfTree(T->right))+1;
}
//求叶子节点数目
int leafNum(BTree &T){
if(T==NULL)
{
return 0;
}
if(T->left==NULL&&T->right==NULL){
return 1;
}
return leafNum(T->left)+leafNum(T->right);
}
//判断是否为平衡二叉树
bool isAVLBt(BTree &T){
if(T==NULL) return true;
else{
if(abs(HegihtOfTree(T->left)-HegihtOfTree(T->right))<=1&&isAVLBt(T->left)&&isAVLBt(T->right))
{
return isAVLBt(T->left)&&isAVLBt(T->right);
}
else{
return false;
}
}
}
//往二叉查找树插入节点
int BSTnode_insert(BSTree &ST,int x){
if(ST==NULL){
ST=(BSTree)malloc(sizeof(BSTnode));
ST->weight=x;
ST->left=NULL;
ST->right=NULL;
}
else if(ST->weight==x){
return 0;//已存在
}
else if(ST->weight<=x){
return BSTnode_insert(ST->right,x);
}
else{
return BSTnode_insert(ST->left,x);
}
return 0;
}
//构建二叉查找树
BSTree creatBST(BSTree &ST,int data[],int length){
for(int i=0;i<length;i++){
printf("%d\n",data[i]);
BSTnode_insert(ST,data[i]);
}
return ST;
}
//二叉查找树的查找 key
BSTnode* BST(BSTree &T,int key,BSTnode** parent,int &flag){
//如果函数参数直接传递的是指针类型,那么在函数内改变指针指向,并不能影响函数外的指针实例。只有传入指针的指针,才能改变指针的指向
BSTnode *result=NULL;
if(T->weight!=key&&T->left==NULL&&T->right==NULL){//没有该节点,自然没有对应的父节点
flag=2;
*parent=NULL;
return NULL;
}
while(T!=NULL&&T->weight!=key){
*parent=T;
printf("父节点的值:%d\n",(*parent)->weight);
if(T->weight>key){
flag=0;//左孩子
printf("往左\n");
printf("%d\n",flag);
return BST(T->left,key,parent,flag);
}
else{
flag=1;//右孩子
printf("往右\n");
printf("%d\n",flag);
return BST(T->right,key,parent,flag);
}
}
result=T;
if(result==NULL)
{
flag=2;//不考虑删除根节点
}
return result;
}
//查找父节点
//BSTnode* BST_parent(BSTree &T,BSTnode* child){
// if(T->left==child||T->right==child){
// return T;
// }
//}
//删除二叉查找树中节点
void DelBSTNode(BSTree &ST,int key,int &falg){
BSTnode *del=BST(ST,key,&parent,flag);
printf("%d\n",flag);
if(!del){
printf("不存在该节点");
}
else if(del->left==NULL&&del->right==NULL&&flag!=2)//非根节点
{
if(flag==0){//删除节点为左孩子
parent->left=NULL;
free(del);
}
if(flag==1){//删除节点为右孩子
parent->right=NULL;
free(del);
}
}
else if(del->left!=NULL&&del->right==NULL)
{
if(flag==0){//删除节点为左孩子
parent->left=del->left;
free(del);
}
if(flag==1){//删除节点为右孩子
parent->right=del->left;
free(del);
}
}
else if(del->left==NULL&&del->right!=NULL)
{
if(flag==0){//删除节点为左孩子
parent->left=del->right;
free(del);
}
if(flag==1){//删除节点为右孩子
parent->right=del->right;
free(del);
}
}
else
{
//左右孩子均非空 在右子树上找中序遍历中第一个子女节点替代被删除节点 实现有待解决
if(flag==0){//删除节点为左孩子
BSTnode *temp=FirstOfMid(del->right);
printf("%d\n",temp->weight);
parent->left=temp;//替换删除节点
temp=temp->right;//把剩余节点接上去
free(del);
}
if(flag==1){//删除节点为右孩子
BSTnode *temp=FirstOfMid(del->right);
printf("%d\n",temp->weight);
parent->right=temp;//替换删除节点
parent->right->left=del->left;//保留删除节点左子树
temp=temp->right;//把剩余节点接上去
//free(temp);
}
}
}
//返回中序遍历的第一个子女
BSTnode* FirstOfMid(BSTree &T){
if(T->left==NULL){
return T;
}
else{
return FirstOfMid(T->left);
}
}