二叉树 ADT接口 遍历算法 常规运算

BTree.h   (结构定义, 基本操作, 遍历)

#define MS 10

typedef struct BTreeNode{
                 char data;
                struct BTreeNode * left
                struct BTreeNode * right;
}BTreeNode;


BTreeNode* InitBTree();
     /*初始化二叉树,即把树根指针置空*/
BTreeNode* CreateBtree(char *a);
     /*根据a所指向的二叉树广义表字符串建立对应的存储结构,返回树根指针*/
int BTreeEmpty(BTreeNode* BT);
     /*判断一颗二叉树是否为空,若是则返回1,否则返回0*/
void Preorder(BTreeNode * BT);
     /*先序遍历的递归算法*/
void Inorder(BTreeNode * BT);
     /*中序遍历的地鬼算法*/
void Postorder(BTreeNode * BT);
     /*后序遍历的递归算法*/
void Levelorder(BTreeNode* BT);
     /*按层遍历由BT指针所指向的二叉树*/
void Inorder(BTreeNode* BT);
     /*对二叉树进行中序遍历的非递归算法*/
int BTreeDepth(BTreeNode * BT);
     /*求BT指向的一颗二叉树深度*/
char* FindBTree(BTreeNode * BT, char x);
     /*从BT所指向的二叉树中查找值为x的节点*/
void PrintBTree(BTreeNode* BT);
     /*输出二叉树的广义表表示*/
BTreeNode* ClearBTree(BTreeNode* BT);
     /*清除二叉树中的所有节点,使之成为一颗空树*/

BTree.c   (二叉树的接口实现)

void Preorder(BTreeNode * BT){

     if(BT != NULL){
         putchar(BT->data);                   //访问根节点
         Preorder(BT->left);                  //先序遍历左子树
         Preorder(BT->right);                 //先序遍历右子树
    }
}

void Inorder(BTreeNode * BT){
     if(BT != NULL){
         Inorder(BT->left);                  //中序遍历左子树
         putchar(BT->data);                  //访问根节点
         Inoreder(BT->right);                //中序遍历右子树
    }
}

void InorderN(BTreeNode* BT){
/*对二叉树进行中序遍历的非递归算法*/
     BTreeNode* s[10];                    //定义用于存储节点指针的栈
     int top = -1;                        //定义栈顶指针并赋初值使s栈为空                  
     BTreeNode* p = BT;                   //定义指针p并使树根指针为它的初值
     while(top != -1 || p != NULL){
         /*当栈非空或p指针非空时执行循环*/
         while(p != NULL){
             /*依次向下访问左子树并使树根指针进栈*/
             top++;
             s[top] = p;
             p = p->left;
         }
         if(top != -1){
         /*树根指针出栈并输出节点的值,接着访问右子树*/
             p = s[top];
             top--;
             putchar(p->data);
             p = p->right;
         }
     } 
}
void Postorder(BTreeNode * BT){
     if(BT != NULL){
         Postorder(BT->left);                //后序遍历左子树
         Postorder(BT->right);               //后序遍历右子树
         putchar(BT->data);                  //访问根节点
    }
}
void Levelorder(BTreeNode* BT){
     /*按层遍历由BT指针所指向的二叉树*/
     /*定义队列所使用的数组空间,元素类型为指向节点的指针类型*/
     BTreeNode* q[MS];          //MS为事先定义的符号常量
     /*定义队首指针和队尾指针,初始均置0表示空队*/
     int front = 0, rear = 0;
     /*将树根指针进队*/
     if(BT != NULL)
         rear = (rear + 1) % MS;
         q[rear] = BT;
     }
     /*当队列非空时执行循环*/
     while(front !- rear){
         BTreeNode* p;  //定义指针变量p
         /*使队首指针指向队首
BTreeNode* InitBTree(){
     /*初始化二叉树,即把树根指针置空*/
            return NULL;
}   

BTreeNode* CreateBtree(char *a){
            /*根据a所指向的二叉树广义表字符串建立对应的存储结构,返回树根指针*/
            BTreeNode * p = NULL;
            /*定义S数组作为存储根节点指针的栈使用*/
            BTreeNode* S[MS];     //MS事先定义的符号常量
            /*定义top作为S栈的栈顶指针,初值为-1,表示空栈*/
            int top = -1;
            /*用k作为处理节点的左子树和右子树的标记,k=1处理左子树,k=2处理右子树*/
            int k;
            /*用i扫描数组a中存储的二叉树广义表字符串,初值为0*/
            int i = 0;
            /*把树根指针置为空,即从空树开始建立二叉树,待建立二叉树结束后返回*/
            BTreeNode BT = NULL;
            /*每循环一次处理一个字符,知道扫描到字符串结束符'\0’为止*/
            while(a[i]){
                 switch(a[i]){
                     case ' ':/*对空格不做任何处理,退出此switch语句*/
                     case '(':
                         if(top ==  MS-1){
                             printf("栈空间太小,需增加MS的值!\n");
                             exit(1);
                         }
                         if(p == NULL){
                             printf("p值不能为空,退出程序!\n");
                             exit(1);
                         }
                         top++;
                         s[top] = p;
                         k = 1;
                         p = NULL;
                         break;
                     case ')':
                         if(top == -1){
                             printf("二叉树广义表字符串有错!\n");
                             exit(1);
                             }
                             top--;
                             break;    
                     case ',':
                         k = 2;
                         break;
                     default:
                         if((a[i] >= 'a' && a[i] <= 'z' ||     a[i] >= 'A' && a[i] <= 'Z')){
                             p = malloc(sizeof(BTreeNode));
                             p->data = a[i];
                             p->left = p->right = NULL;
                             if(BT == Null) BT = P;
                             else{
                                 if(k == 1)s[top]->lef = p;
                                 else s[top]->right = p;
                             }
                         }
                         else{
                             printf("广义表字符串出错!\n");
                             exit(1);
                         }
                 }
                 /*为扫描下一个字符修改i值*/
                 i++;
             }
              return BT;
}             
int BTreeEmpty(BTreeNode* BT){
     /*判断一颗二叉树是否为空,若是则返回1,否则返回0*/
     if(BT== NULL) return 1;
     else return 0;
}
                
int BTreeDepth(BTreeNode * BT){
     /*求BT指向的一颗二叉树深度*/
     if(BT != NULL) return 0;
     else{
         /*计算左子树深度*/
         int dep1 = BTreeDepth(BT->left);
         /*计算右子树深度*/
         int dep1 = BTreeDepth(BT->right);
         
         /*返回树的深度*/
         if(dep1 > dep2) return dep1 + 1;
         else  return dep2 + 1;
    }
}

char* FindBTree(BTreeNode * BT, char x){
     /*从BT所指向的二叉树中查找值为x的节点*/
         if(BT == NULL) return  NULL;
         else{
       /*树节点的值等于x则返回元素地址*/
             if(BT->data == x) return &(BT->data);
             else{
                 char* p;
        /*向左子树查找若成功则继续返回元素的地址*/
                 if(p = FindBTree(BT->left,x)) return p;
        /*向右子树查找若成功则继续返回元素的地址*/
                 if(p = FindBTree(BT->right,x)) return p;
        /*左右子树查找均失败则返回空*/
                 return NULL;
             }
         }
}

void PrintBTree(BTreeNode* BT){
  /*输出二叉树的广义表表示*/
     /*树为空时自然结束递归,否则执行如下操作*/
     if(BT != NULL){
     /*输出根节点的值*/
         putchar(BT->data);
     /*输出左右子树*/
         if(BT->left != NULL || BT->right != NULL){
             putchar('(');                           //输出左括号
             PrintBTree(BT->left);                   //输出左子树
             if(BT->right != NULL) putchar(',');     //若右子树不为空则输出逗号分隔符
             
             PrintBTree(BT -> right);                //输出右子树
             putchar(')');                           //输出右括号
         }
     }
}

BTreeNode* ClearBTree(BTreeNode* BT){
             if(BT == NULL) return NULL;
             else{
                  ClearBTree(BT->left);              //删除左子树
                  ClearBTree(BT->right);             //删除右子树
                  free(BT);                          //释放根节点
                  return NULL;                       //返回空指针      
             }
}

BTreeTest.c   (二叉树运算调试程序)

#include "BTree.h"

int main(void){
     BTreeNode *p;
     char *k;
     int n1;
     char *a = "A(B(C),D(E(F,G),H(,I)))";
     P = InitBTree();                              //建立空树
     p = CreateBTree(a);                           //按照广义表形式的二叉树建立二叉链表
     Preorder(p); putchar('\n');                   //先序遍历
     Inorder(p)   putchar('\n');                                  //中序遍历 
     Postorder(p)  putchar('\n');                    //后序遍历
     Levelorder(p)  putchar('\n');                    //按层遍历
     InorderN(p)  putchar('\n');                             //中序非递归遍历
     printf("%d\n",BTreeDepth(p));                           //求二叉树深度
     k = FindBTree(p, 'I'); if(k!=NULL) printf("%c\n", *k);   //查找二叉树
     PrintBTree(p);                                       //输出二叉树
     p = ClearBTree(p);                                   //清空二叉树
     n1 = BTreeEmpty(P);  printf("%d\n", n1);             //判断树是否为空
     
     }

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值