vc6.0 C语言 树的一些算法实现

代码仅作纪念,作为对数据结构----树的一点小总结吧。不保证其权威性。也许有缺漏。算法大佬轻喷。

#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);
    }
}

 

猜你喜欢

转载自blog.csdn.net/qq_28449863/article/details/79689801
今日推荐