zoukankan      html  css  js  c++  java
  • 树和二叉树



    //BiTree.h
    
    struct BiTNode   //采用二叉链表存储结构
    {
     char data;
     struct BiTNode* lchild;
     struct BiTNode* rchild;
    }BiTNode;
    
    
    struct BiTNode* CreateBiTree();  
    int DestroyBiTree(struct BiTNode* T);
    int visit(char elem);
    
    //递归遍历算法
    int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));
    int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));
    int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem));
    
    //非递归遍历算法
    void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
    void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
    void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem));
    


    //stack.h 堆栈数据结构,用于非递归算法中的附加空间
    
    #define STACK_SIZE 256
    
    struct stack
    {
     struct BiTNode* elem[STACK_SIZE];
     int top;  //top总是指向栈顶元素的上一个元素
     int bottom; //恒0
    };
    void initStack(struct stack* s);
    struct BiTNode* getTop(struct stack* s);
    struct BiTNode* pop(struct stack* s);
    void push(struct stack* s,struct BiTNode* p);
    int isEmpty(struct stack* s);
    


    //stack.c 堆栈的实现
    
    #include<stdio.h>
    #include<string.h>
    #include "stack.h"
    
    //初始化堆栈为0,栈指针为0
    void initStack(struct stack* s)
    {
     memset(s->elem,0,STACK_SIZE);
     s->top = s->bottom = 0;
    }
    
    //获取栈顶元素,栈顶指针不变
    struct BiTNode* getTop(struct stack* s)
    {
     return s->elem[s->top-1];
    }
    
    //弹出&返回栈顶元素
    struct BiTNode* pop(struct stack* s)
    {
     if(s->top == s->bottom)  //若栈空
     {
      printf("Stack is empty!
    ");
      return 0;
     }
    
     --s->top;
     return s->elem[s->top];
    }
    
    //将pB指针压入栈中
    void push(struct stack* s,struct BiTNode* pB)
    {
     if(s->top<STACK_SIZE)  //栈未满
     {
      s->elem[s->top] = pB;
      ++s->top;
     }
     else  
      printf("Stack is full!
    ");
    }
    
    //判断栈是否为空,空返回非0
    int isEmpty(struct stack* s)
    {
     return s->top == s->bottom;
    }
    


    //BiTree.c 二叉树创建、销毁、递归算法实现
    
    #include<stdio.h>
    #include<malloc.h>
    #include "BiTree.h"
    #include "stack.h"
    
    struct BiTNode* CreateBiTree() //采用先序递归方法创建一棵二叉树
    {
     struct BiTNode* T;
     char ch,tmp;
     printf("please input the value of the node:
    ");
     scanf("%c",&ch);
     tmp = getchar(); //忽略回车符
     if(ch == ''&'')    //输入&符号表示此节点为空
     {
      printf("Null BiTreeNode Created!
    ");
      T = NULL;
      return NULL;
     }
     
     T = (struct BiTNode *)malloc(sizeof(BiTNode)); //为当前节点分配内存
     if(!T)
     {
      printf("Allocate memory failed!
    ");
      return NULL;
     }
    
     T->data = ch;  //为当前节点赋值
    
     T->lchild = CreateBiTree();  //递归创建左子树
     T->rchild = CreateBiTree(); //递归创建右子树
    
     return T; 
    }
    
    //销毁二叉树,销毁成功返回0,错误返回1
    int DestroyBiTree(struct BiTNode* T)
    {
     if(T)
     {
      struct BiTNode* lchild = T->lchild;
      struct BiTNode* rchild = T->rchild;
      free(T);
      if(0 == DestroyBiTree(lchild))
      {
       if(0 == DestroyBiTree(rchild))
        return 0;
       else
        return 1;
      }
     } 
     return 0;
    }
    //访问节点元素
    int visit(char elem)
    {
     if(elem == ''&'')
      return 1;
     printf("%c ",elem);
     return 0;
    }
    
    //先序遍历递归算法,返回值为0表示遍历成功,1为失败
    int PreOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
    {
     if(T)
     {
      if(0 != visit(T->data))  //访问根节点
       return 1;
    
      if(T->lchild)
      {
       if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
        return 1;
      }
      
      if(T->rchild)
      {
       if(0 != InOrderTraverse_R(T->rchild, visit)) //递归遍历右子树
        return 1;
      }  
     } 
     return 0;   
    }
    
    //中序遍历递归算法,返回值为0表示遍历成功,1为失败
    int InOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
    {
     if(T)
     {
      if(T->lchild)
      {
       if(0 != InOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
        return 1;
      }
      
      if(0 != visit(T->data))  //访问根节点
       return 1;
      
      if(T->rchild)
      {
       if(0 != InOrderTraverse_R(T->rchild,visit)) //递归遍历右子树
        return 1;
      }  
     } 
     return 0;  
    }
    
    //后序遍历递归算法,返回0表示遍历成功,1为失败
    int PostOrderTraverse_R(struct BiTNode* T, int (*visit)(char elem))
    {
     if(T)
     {
      if(T->lchild)
      {
       if(0 != PostOrderTraverse_R(T->lchild,visit)) //递归遍历左子树
        return 1;
      }
      
      if(T->rchild)
      {
       if(0 != PostOrderTraverse_R(T->rchild,visit)) //递归遍历右子树
        return 1;
      }
      
      if(0 != visit(T->data))  //访问根节点
       return 1;
     } 
     return 0;     
    }
    
    //先序遍历非递归算法
    void PreOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
    {
     struct stack ss;
     struct BiTNode* p = T;
     initStack(&ss); 
     while(p||!isEmpty(&ss))
     {
      if(p)
      {
       visit(p->data);
       push(&ss,p);
       p=p->lchild;
      }
      else
      {
       p = getTop(&ss);
       pop(&ss);
       p = p->rchild;
      }
     }
    }
    
    //中序遍历非递归算法
    void InOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
    {
     struct stack ss;
     struct BiTNode* p;
     initStack(&ss);
    
     push(&ss,T);
     while(!isEmpty(&ss))
     {
      while(p = getTop(&ss)) 
       push(&ss,p->lchild); //向左走到尽头
      p = pop(&ss);  //空指针退栈
    
      if(!isEmpty(&ss))
      {
       p = pop(&ss);
       visit(p->data);  //访问节点
       push(&ss,p->rchild); //向右一步
      }
     }
    }
    
    //后序遍历非递归算法
    void PostOrderTraverse(struct BiTNode* T, int (*visit)(char elem))
    {
     struct stack ss;
     struct BiTNode* p = T;
     struct BiTNode* q;
     initStack(&ss); //初始化空栈
    
     while(p || !isEmpty(&ss))
     {
      if(p)
      {
       push(&ss,p);
       p = p->lchild;
      }
      else
      {
       p =getTop(&ss);
       if(p)
       {
        push(&ss,NULL);
        p = p->rchild;
       }
       else
       {
        pop(&ss);
        q = pop(&ss);
        visit(q->data);
       }
      }
     }
    }
    



    //main.c 测试主程序
    
    #include<stdio.h>
    #include "BiTree.h"
    
    int main()
    {
     struct BiTNode* bt = 0;
     bt = CreateBiTree(bt);
     printf("先序遍历序列:
    ");
     PreOrderTraverse_R(bt,visit);
     printf("
    中序遍历序列:
    ");
     InOrderTraverse_R(bt,visit);
     printf("
    后序遍历序列:
    ");
     PostOrderTraverse_R(bt,visit);
    
     printf("
    非递归先序遍历序列:
    ");
     PreOrderTraverse(bt,visit);
    
     printf("
    非递归中序遍历序列:
    ");
     InOrderTraverse(bt,visit);
    
     printf("
    非递归后序遍历序列:
    ");
     PostOrderTraverse(bt,visit);
     DestroyBiTree(bt);
     return 0;
    }



    查找结点



    查找结点就是遍历二叉树中的每一个节点,逐个比较数据,当找到目标数据时将返回该数据所在结点的指针。


    代码如下:
    CBTType *TreeFindNode(CBTType *treeNode,DATA data)
    {
     CBTType *ptr;
     if(treeNode==NULL)
     {
      return NULL;
     }else
     {
      if(treeNode->data==data)
      {
       return treeNode;
      }
      else        //分别向左右子树查找   
      {

       if(ptr=TreeFindNode(treeNode->left,data))  //左子树递归查找 
       {

        return ptr;
       }
       else if(ptr=TreeFindNode(treeNode->right,data))         //右子树递归查找 
       {
        return ptr;
       }
       else
       {
        return NULL;
       }
      }
     } 



    输入参数treeNode为待查找的二叉树的根结点,输入参数data为待查找的结点数据。程序中首先判断根结点是否为空,然后根据数据判断是否为根结点,然后分别向左右子树进行查找,采用递归的方法进行查找,查找到该结点则返回结点对应的指针;如果全都查找不到,则返回NULL。



    计算二叉树的深度

    计算二叉树深度就是计算二叉树中结点的最大层数,这里往往需要采用递归算法来实现。



    int TreeDepth(CBTType *treeNode)
    {
     int depleft,depright;
     if(treeNode==NULL)
     {
      return 0;     //结点为空的时候,深度为0
     }
     else
     {
      depleft=TreeDepth(treeNode->left);  //左子树深度(递归调用)
      depright=TreeDepth(treeNode->right);         //右子树深度(递归调用)
      if(depleft)
      {
       return ++depleft;
      }
      else
      {
       return ++depright;
      }
     }
    }

    输入参数treeNode为待计算的二叉树的根结点。首先判断根节点是否为空,然后分别按照递归调用来计算左子树深度和右子树深度,从而完成整个二叉树深度的计算。  




    版权声明:

  • 相关阅读:
    【原】OpenEdx平台安装及出错解决方案
    【转】R语言中的并行计算——搭建R的集群
    【转】机器学习中的相似性度量
    A--Scikit-Learn入门
    A--最近邻分类器-KNN
    A--K-Means快速聚类
    A--无监督学习算法示例: DBSCAN(聚类)
    A-无监督学习算法示例:层次聚类
    A-岭回归的python'实现
    A--利用梯度下降求解逻辑回归的python实现
  • 原文地址:https://www.cnblogs.com/walccott/p/4957062.html
Copyright © 2011-2022 走看看