zoukankan      html  css  js  c++  java
  • 二叉树的相关操作(c语言)

    二叉树的相关操作:包括先序序列+中序序列建树丶后序序列+中序序列建树丶层次序列+中序序列建树;先序遍历丶中序遍历丶后序遍历丶层次遍历;二叉树的深度及最大宽度;度分别为0,1,2的节点个数以及总结点个数

    #include<stdio.h>

    #include<malloc.h>

    #include<stdlib.h>

    #include<string.h>

    //二叉树节点结构体

    struct BinaryTreeNode{

        char m_key;

        BinaryTreeNode* m_pLeft;

        BinaryTreeNode* m_pRight;

    };

    // 定义栈的存储表示

    #define STACK_INIT_SIZE 100

    #define STACKINCREMENT 10

    struct SqStack{

           char* base;

           char* top;

           int stacksize;

    };

    // 定义队列的存储表示

    struct QNode {

           BinaryTreeNode data; //元素为一棵树

           struct QNode* next;

    };

    struct LinkQueue{

           QNode* front;

           QNode* rear;

    };

    // 栈的基本操作的函数

    void InitStack(SqStack &S) {

           S.base = (char*)malloc(STACK_INIT_SIZE * sizeof(char));

           if (!S.base) exit(-1);

           S.top = S.base;

           S.stacksize = STACK_INIT_SIZE;

    }

    bool StackEmpty(SqStack S) {

           if (S.top == S.base) return true;

           else return false;

    }

    void Push(SqStack &S, char e) {

           if (S.top - S.base >= S.stacksize) {

                  S.base = (char*)realloc(S.base,

                         (S.stacksize + STACKINCREMENT) * sizeof(char));

                  if (!S.base)  exit(-1);

                  S.top = S.base + S.stacksize;

                  S.stacksize += STACKINCREMENT;

           }

           *S.top++ = e;

    }

    void Pop(SqStack &S, char &e) {

           if (S.top == S.base)  exit(-1);

           e = *--S.top;

    }

    // 队列的基本操作的函数

    void InitQueue(LinkQueue &Q) {

           Q.front = Q.rear = (QNode*)malloc(sizeof(QNode));

           if (!Q.front)  exit(-1);

           Q.front->next = NULL;

    }

    bool QueueEmpty(LinkQueue Q) {

           if (Q.front == Q.rear) return true;

           else return false;

    }

    void EnQueue(LinkQueue &Q, BinaryTreeNode e) {

           QNode* p;

           p = (QNode*)malloc(sizeof(QNode));

           if (!p)  exit(-1);

           p->data = e;

           p->next = NULL;

           Q.rear->next = p;

           Q.rear = p;

    }

    void DeQueue(LinkQueue &Q, BinaryTreeNode &e) {

           if (Q.front == Q.rear)  exit(-1);

           QNode*  p;

           p = Q.front->next;

           e = p->data;

           Q.front->next = p->next;

           if (Q.rear == p) Q.rear = Q.front;

           free(p);

    }

    /****************************************

    func:根据前序序列和中序序列构建二叉树

    para:preOrder:前序序列;midOrder:中序序列;len:节点数

    ****************************************/

    BinaryTreeNode* construct1(char* preOrder,char* midOrder,int len){

        if(preOrder==NULL||midOrder==NULL||len<=0)

            return NULL;

        //先根遍历(前序遍历)的第一个值就是根节点的键值

        char rootKey=preOrder[0];

        BinaryTreeNode* root=new BinaryTreeNode;

        root->m_key=rootKey;

        root->m_pLeft=root->m_pRight=NULL;

        if(len==1 && *preOrder==*midOrder)//只有一个节点

            return root;

        //在中根遍历(中序遍历)中找到根节点的值

        char* rootMidOrder=midOrder;

        int leftLen=0; //左子树节点数

        while(*rootMidOrder!=rootKey&&rootMidOrder<=(midOrder+len-1)){

            ++rootMidOrder;

            ++leftLen;

        }

        if(*rootMidOrder!=rootKey)//在中根序列未找到根节点,输入错误

            return NULL;

        if(leftLen>0){ //构建左子树

            root->m_pLeft=construct1(preOrder+1,midOrder,leftLen);

        }

        if(len-leftLen-1>0){ //构建右子树

            root->m_pRight=construct1(preOrder+leftLen+1,rootMidOrder+1,len-leftLen-1);

        }

        return root;

    }

    /****************************************

    func:根据后序序列和中序序列构建二叉树

    para:postOrder:后序序列;midOrder:中序序列;len:节点数

    ****************************************/

    BinaryTreeNode* construct2(char* postOrder,char* midOrder,int len)

    {

           if(postOrder==NULL || midOrder==NULL || len<=0)

                  return NULL;

           //后根遍历(后序遍历)的最后一个值就是根节点的键值

           char rootKey=*(postOrder+len-1); //获取根节点的值

           BinaryTreeNode* root=new BinaryTreeNode;

        root->m_key=rootKey;

        root->m_pLeft=root->m_pRight=NULL;

            if(len==1 && *postOrder==*midOrder)//只有一个节点

            return root;

             //在中根遍历(中序遍历)中找到根节点的值

        char* rootMidOrder=midOrder;

        int leftLen=0; //左子树节点数

        while(*rootMidOrder!=rootKey&&rootMidOrder<=(midOrder+len-1)){

            ++rootMidOrder;

            ++leftLen;

        }

        if(*rootMidOrder!=rootKey)//在中根序列未找到根节点,输入错误

            return NULL;

        if(leftLen>0){ //构建左子树

            root->m_pLeft=construct2(postOrder,midOrder,leftLen);

        }

        if(len-leftLen-1>0){ //构建右子树

            root->m_pRight=construct2(postOrder+leftLen,rootMidOrder+1,len-leftLen-1);

        }

        return root;

    }

    /****************************************

    func:根据后序序列和层次序列构建二叉树

    para:level:层次序列;midOrder:中序序列;root:二叉树指针引用

    ****************************************/

    void construct3(char* level,char* midOrder,BinaryTreeNode* &root)

    {

        int i;

           int len=strlen(level); //取得层次遍历长度

        int pos=0;

        if(len==0 || level==NULL || midOrder==NULL)

           {

                  return;

           }

        char *p=strchr(midOrder,level[0]);

        if(p==NULL)     //如果为空则抛弃第一个,跳到下一个;

        {

            char *L=(char*)malloc(sizeof(char)*len);    //开辟数组

            strncpy(L,level+1,len-1);       //舍弃第一个

            L[len-1]=0;

           construct3(L,midOrder,root);     //调用建树函数

            return ;

        }

        pos=p-midOrder;      //得到中序遍历左子树字符串长度

        root->m_key=level[0];   //为根节点赋值

        root->m_pLeft=NULL;

        root->m_pRight=NULL;

        if(pos!=0)  //左子树的递归调用

        {

            root->m_pLeft=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));

            char *left_level=(char*)malloc(sizeof(char)*len);

            char *left_inor=(char*)malloc(sizeof(char)*(pos));

            strncpy(left_level,level+1,len-1);  //舍去层次遍历第一个

            strncpy(left_inor,midOrder,pos);     //截取左子树字符串

            left_level[len-1]=0;

            left_inor[pos]=0;

            construct3(left_level,left_inor,root->m_pLeft);

        }

        if(pos < strlen(midOrder)-1)      //右子树的递归调用

        {

            root->m_pRight=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));

            char *right_level=(char*)malloc(sizeof(char)*(len));

            char *right_inor=(char*)malloc(sizeof(char)*(len-pos));

            strncpy(right_level,level+1,len-1);

            strncpy(right_inor,midOrder+pos+1,len-pos-1);

            right_level[len-1]=0;

            right_inor[len-pos-1]=0;

            construct3(right_level,right_inor,root->m_pRight);

        }

    }

    //先根递归遍历

    void preOrderRecursion(BinaryTreeNode* root){

        if(root==NULL)

            return;

           printf("%c ",root->m_key);

        preOrderRecursion(root->m_pLeft);

        preOrderRecursion(root->m_pRight);

    }

    //中根递归遍历

    void midOrderRecursion(BinaryTreeNode* root){

        if(root==NULL)

            return;

        midOrderRecursion(root->m_pLeft);

           printf("%c ",root->m_key);

        midOrderRecursion(root->m_pRight);

    }

    //后根递归遍历

    void postOrderRecursion(BinaryTreeNode* root){

        if(root==NULL)

            return;

        postOrderRecursion(root->m_pLeft);

        postOrderRecursion(root->m_pRight);

        printf("%c ",root->m_key);

    }

    //层次遍历二叉树,使用队列实现

    void breadthFirstOrder(BinaryTreeNode* root){

           LinkQueue Q;

           InitQueue(Q);

           BinaryTreeNode p;

           if (root)

                  EnQueue(Q,*root);

           else

                  exit(-1);

       while (!QueueEmpty(Q)) {

                  DeQueue(Q, p);

                  printf("%c ",p.m_key);

                  if (p.m_pLeft)

                         EnQueue(Q,*p.m_pLeft);

                  if (p.m_pRight)

                         EnQueue(Q,*p.m_pRight);

           }

    }

    //返回二叉树的深度

     int BiTreeDepth( BinaryTreeNode* T)

     {

       int i,j;

       if(!T)

         return 0;

       if(T->m_pLeft)

         i=BiTreeDepth(T->m_pLeft);

       else

         i=0;

       if(T->m_pRight)

         j=BiTreeDepth(T->m_pRight);

       else

         j=0;

       return i>j?i+1:j+1;

     }

     //求二叉树的最大宽度

    int LevelWidth(BinaryTreeNode* root,int level)

    {

           if(!root)return 0;

           else

           {

                  if(level==1)

                         return 1;

                  level=LevelWidth(root->m_pLeft,level-1)+LevelWidth(root->m_pRight,level-1);

           }

           return level;

    }

    int Width(BinaryTreeNode* root)

    {

           int width,i;

           int w[20];

           for(i=0;i<20;i++)

                  w[i]=0;

           if(!root)

                  width=0;

           else

           {

                  for(i=0;i<=BiTreeDepth(root);i++)

                         w[i]=LevelWidth(root,i+1);

           }

           i=0;

           while(w[i])

           {

                  if(w[i]>width)

                         width=w[i];

                  i++;

           }

           return width;

    }

    //求度为0的节点个数

    int NodeNumber_0(BinaryTreeNode* T)

    {

           int i=0;

           if(T)

           {

                  if(T->m_pLeft==NULL && T->m_pRight==NULL)

                  {

                         i=1;

                  }

                  else

                  {

                         i=NodeNumber_0(T->m_pLeft) + NodeNumber_0( T->m_pRight );

                  }

           }

           return i;

    }

    //求度为1的节点个数

    int NodeNumber_1(BinaryTreeNode* T)

    {

           int i=0;

           if(T)

           {

                  if( (T->m_pLeft==NULL && T->m_pRight!=NULL) || (T->m_pLeft!=NULL && T->m_pRight==NULL))

                  {

                         i=1+NodeNumber_1(T->m_pLeft)+NodeNumber_1(T->m_pRight);

                  }

                  else

                  {

                         i=NodeNumber_1(T->m_pLeft)+NodeNumber_1(T->m_pRight);

                  }

           }

           return i;

    }

    //求度为2的节点个数

    int NodeNumber_2(BinaryTreeNode* T)

    {

           int i=0;

           if(T)

           {

                  if((T->m_pLeft!=NULL)&&(T->m_pRight!=NULL))

                  {

                         i=1+NodeNumber_2(T->m_pLeft) + NodeNumber_2(T->m_pRight);

                  }

                  else

                  {

                         i= NodeNumber_2(T->m_pLeft) + NodeNumber_2(T->m_pRight);

                  }

           }

           return i;

    }

    int main(){

           int depth;

           int width;

           int num0;

           int num1;

           int num2;

           int sum;

        //二叉树1先根序列

        char preOrder1[9]={'1','2','4','7','3','5','6','8'};

        //二叉树1中根序列

        char midOrder1[9]={'4','7','2','1','5','3','8','6'};

           //二叉树1后根序列

           char postOrder1[9]={'7','4','2','5','8','6','3','1'};

           //二叉树1层次序列

           char cengOrder1[9]={'1','2','3','4','5','6','7','8'};

           //二叉树2先根序列

           char preOrder2[8]={'A','B','C','D','E','G','F'};

           //二叉树2中根序列

           char midOrder2[8]={'C','B','E','G','D','F','A'};

           //二叉树2后根序列

           char postOrder2[8]={'C','G','E','F','D','B','A'};

           //二叉树2层次序列

           char cengOrder2[8]={'A','B','C','D','E','F','G'};

           //二叉树3先根序列

           char preOrder3[9]={'H','D','A','C','B','G','F','E'};

           //二叉树3中根序列

           char midOrder3[9]={'A','D','C','B','H','F','E','G'};

           //二叉树3后根序列

           char postOrder3[9]={'A','B','C','D','E','F','G','H'};

           //二叉树3层次序列

           char cengOrder3[9]={'H','D','G','A','C','F','B','E'};

        //先根序列+中根序列建树1

           printf("先根序列+中根序列建树1 ");

        BinaryTreeNode* root1=construct1(preOrder1,midOrder1,8);

        //先序遍历树1

           printf("该二叉树的先序遍历为:");

        preOrderRecursion(root1);

        printf(" ");

        //中序遍历树1

           printf("该二叉树的中序遍历为:");

        midOrderRecursion(root1);

        printf(" ");

        //后序遍历树1

           printf("该二叉树的后序遍历为:");

        postOrderRecursion(root1);

        printf(" ");

       //层次遍历树1

           printf("该二叉树的层次遍历为:");

        breadthFirstOrder(root1);

           printf(" ");

           //二叉树1的深度

           depth=BiTreeDepth(root1);

           printf("该二叉树的深度为%d ",depth);

          

           //二叉树1的最大宽度

           width=Width(root1);

           printf("该二叉树的最大宽度为%d ",width);

          

           //二叉树1度为0的节点个数

           num0=NodeNumber_0(root1);

           printf("该二叉树度为0的节点个数为%d ",num0);

           //二叉树1度为1的节点个数

           num1=NodeNumber_1(root1);

           printf("该二叉树度为1的节点个数为%d ",num1);

           //二叉树1度为2的节点个数

           num2=NodeNumber_2(root1);

           printf("该二叉树度为2的节点个数为%d ",num2);

           //二叉树1总结点个数

           sum=num0+num1+num2;

           printf("该二叉树度的总节点个数为%d ",sum);

           printf(" ");

            //  后根序列+中根序列建树2

           printf("后根序列+中根序列建树2 ");

           BinaryTreeNode* root2=construct2(postOrder2,midOrder2,7);

            //先序遍历树2

           printf("该二叉树的先序遍历为:");

        preOrderRecursion(root2);

        printf(" ");

        //中序遍历树2

           printf("该二叉树的中序遍历为:");

        midOrderRecursion(root2);

        printf(" ");

        //后序遍历树2

           printf("该二叉树的后序遍历为:");

        postOrderRecursion(root2);

        printf(" ");

       //层次遍历树2

           printf("该二叉树的层次遍历为:");

        breadthFirstOrder(root2);

           printf(" ");

           //二叉树2的深度

           depth=BiTreeDepth(root2);

           printf("该二叉树的深度为%d ",depth);

          

           //二叉树2的最大宽度

           width=Width(root2);

           printf("该二叉树的最大宽度为%d ",width);

          

           //二叉树2度为0的节点个数

           num0=NodeNumber_0(root2);

           printf("该二叉树度为0的节点个数为%d ",num0);

           //二叉树2度为1的节点个数

           num1=NodeNumber_1(root2);

           printf("该二叉树度为1的节点个数为%d ",num1);

           //二叉树2度为2的节点个数

           num2=NodeNumber_2(root2);

           printf("该二叉树度为2的节点个数为%d ",num2);

           //二叉树2总结点个数

           sum=num0+num1+num2;

           printf("该二叉树度的总节点个数为%d ",sum);

           printf(" ");

          

           //层次序列+中根序列建树3

           printf("层次序列+中根序列建树3 ");

           BinaryTreeNode* root3;

           root3=(BinaryTreeNode*)malloc(sizeof(BinaryTreeNode));

           construct3(cengOrder3,midOrder3,root3);

           //先序遍历树3

           printf("该二叉树的先序遍历为:");

        preOrderRecursion(root3);

        printf(" ");

        //中序遍历树3

           printf("该二叉树的中序遍历为:");

        midOrderRecursion(root3);

        printf(" ");

        //后序遍历树3

           printf("该二叉树的后序遍历为:");

        postOrderRecursion(root3);

        printf(" ");

       //层次遍历树3

           printf("该二叉树的层次遍历为:");

        breadthFirstOrder(root3);

           printf(" ");

           //二叉树3的深度

           depth=BiTreeDepth(root3);

           printf("该二叉树的深度为%d ",depth);

          

           //二叉树3的最大宽度

           width=Width(root3);

           printf("该二叉树的最大宽度为%d ",width);

          

           //二叉树3度为0的节点个数

           num0=NodeNumber_0(root3);

           printf("该二叉树度为0的节点个数为%d ",num0);

           //二叉树3度为1的节点个数

           num1=NodeNumber_1(root3);

           printf("该二叉树度为1的节点个数为%d ",num1);

           //二叉树3度为2的节点个数

           num2=NodeNumber_2(root3);

           printf("该二叉树度为2的节点个数为%d ",num2);

           //二叉树3总结点个数

           sum=num0+num1+num2;

           printf("该二叉树度的总节点个数为%d ",sum);

           return 0;

    }

    运行结果

     

  • 相关阅读:
    spark读取文件时对字符编码的支持
    SparkSQL 数据分页及Top N
    linux下添加hadoop用户
    Window 10 WSL 下hadoop 伪分布式安装
    Window 10下spark shell使用sparksql 时的 “entry in command string: null ls -F C: mphive”问题解决
    spark数据怎样输出到Sql Server
    spark standalone集群模式下一个启动问题的解决
    Ubuntu 上redis 5.0的安装
    apache ambari 部署分布式系统
    Ubuntu18.04 下 Spark 2.4.3 standalone模式集群部署
  • 原文地址:https://www.cnblogs.com/Dearmyh/p/9976228.html
Copyright © 2011-2022 走看看