二叉树的总结

1、二叉树的数据结构


typedef struct TreeNode{

char value;\\符号

struct TreeNode * LeftChild;\\左孩子

struct TreeNode * RightChild;\\右孩子

}TreeNode,*Tree;

2、二叉树的创建

Tree CreatTree()
{   
    char value;
    TreeNode * Node;
    scanf("%c",&value);
    if(value=='#')//#代表空节点,用来控制树的结构
        Node=NULL;
    else{
        Node=(TreeNode *)malloc(sizeof(TreeNode));
        Node->value=value;
        Node->LeftChild=CreatTree();
        Node->RightChild=CreatTree();
}
    return Node;

}
树的结构:
Paste_Image.png
输入:AB#C##D## ;

3、二叉树的遍历

二叉树的遍历分为前序遍历、中序遍历、后序遍历。主要分别在于根节点的遍历优先级。前序:根、左、右;中序:左、根、右;后序:左、右、根。
①递归遍历

Tree Travel(Tree tree)
{
    if(tree==NULL)
          return NULL;
    else
    {        
               /****前序遍历****/
          printf("%c\t",tree->value);
          Travel(tree->LeftChild);
          Travel(tree->RightChild);

              /****中序遍历****/
          Travel(tree->LeftChild);
          printf("%c\t",tree->value);
          Travel(tree->RightChild);

              /****后序遍历****/
          Travel(tree->LeftChild);
          Travel(tree->RightChild); 
          printf("%c\t",tree->value);
    }
}

②非递归遍历

void PreTravel(Tree tree)
{
   stack<Tree> s;
   while(tree||!s.empty())
   {
       while(tree)
       {
           printf("%c\t",tree->value);
           s.push(tree);
           tree=tree->LeftChild;
       }
       tree=s.top();
       s.pop();
       tree=tree->RightChild;
      
   }
}
void MiddleTravel(Tree tree)
{
   stack<Tree> s;
   while(tree||!s.empty())
   {
       while(tree)
       {
           s.push(tree);
           tree=tree->LeftChild;
       }
       tree=s.top();
      printf("%c\t",tree->value);
      s.pop();
      tree=tree->RightChild;
   }
}

void PostTravel(Tree T)  // 后序遍历的非递归      
{      
    stack<Tree> S;      
    Tree curr = T ;           // 指向当前要检查的节点    
    Tree previsited = NULL;    // 指向前一个被访问的节点    
    while(curr != NULL || !S.empty())  // 栈空时结束      
    {      
        while(curr != NULL)            // 一直向左走直到为空    
        {      
            S.push(curr);      
            curr = curr->LeftChild;      
        }      
        curr = S.top();    
        // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点    
        if(curr->RightChild== NULL || curr->RightChild== previsited)      
        {      
            cout<<curr->value<<"  ";      
            previsited = curr;      
            S.pop();      
            curr = NULL;      
        }      
        else    
            curr = curr->RightChild;      // 否则访问右孩子    
    }      
}  

4、求二树的高度

对此问题我们可以采用递归的思想,将问题进行分解。树的高度=max{左子树的高度,右子树的高度}+1。

Paste_Image.png
int Height(Tree tree)
{
  int high;
  int left_high;
  int right_high;
  if(tree==NULL)
      return 0;
  left_high=Height(tree->LeftChild);
  right_high=Height(tree->RightChild);
  if(left_high>right_high)
        high=left_high+1;
  else
        high=right_high+1;
  return high;
}

5、二叉树的层次遍历

算法步骤:

①将根结点压进队列Q;
②对队列Q进行出队操作,打印出队结点信息,然后将出队结点的左右孩子结点(当其孩子结点存在的情况下)压入队列Q;
③重复步骤②的操作直至队列为空

void HierarchyTravel(Tree tree)
{
     LinkQueue q;;
     Init(&q);
     EnQueue(&q,*tree);
     TreeNode node;
     printf("HierarchyTravel:");
     while(!QueueEmpty(&q))
     {
         DeQueue(&q,&node);
         printf("%c\t",node.value);
         if(node.LeftChild)
             EnQueue(&q,*node.LeftChild);
         if(node.RightChild)
             EnQueue(&q,*node.RightChild);
     }
}

6、测试代码

#include "stdafx.h"
#include "stdlib.h"
typedef struct TreeNode{
    char value;
    struct TreeNode * LeftChild;
    struct TreeNode * RightChild;
}TreeNode,*Tree;
typedef struct QNode{
    TreeNode Node;
    struct QNode * next;
}QNode,*QueueNode;
typedef struct LinkQueue{
    QueueNode front;
    QueueNode rear;
}LinkQueue;
Tree CreatTree()
{   
    char value;
    TreeNode * Node;
    scanf("%c",&value);
    if(value=='#')
        Node=NULL;
    else{
        Node=(TreeNode *)malloc(sizeof(TreeNode));
        Node->value=value;
        Node->LeftChild=CreatTree();
        Node->RightChild=CreatTree();
}
    return Node;

}
void PreTravel(Tree tree)
{
    if(tree)
    {
        printf("%c\t",tree->value);
        PreTravel(tree->LeftChild);
        PreTravel(tree->RightChild);
    }
}
void MiddleTravel(Tree tree)
{
    if(tree)
    {   
        MiddleTravel(tree->LeftChild);
        printf("%c\t",tree->value);
        MiddleTravel(tree->RightChild);
    }
}
void PostTravel(Tree tree)
{
    if(tree)
    {   
        PostTravel(tree->LeftChild);    
        PostTravel(tree->RightChild);
        printf("%c\t",tree->value);
    }
}
void Init(LinkQueue *q)//队列初始化
{
    q->front=q->rear=(QueueNode)malloc(sizeof(QNode));

    if(!q->front)
        exit(0);
    q->front->next=NULL;

}
void EnQueue(LinkQueue *q,TreeNode treenode)//入队
{
    QueueNode qnode;
    qnode=(QueueNode)malloc(sizeof(QNode));
    qnode->Node=treenode;
    /****插入队列****/
    qnode->next=q->rear->next;
    q->rear->next=qnode;
    /****改队尾指针****/
    q->rear=qnode;
}
void DeQueue(LinkQueue *q,TreeNode *node)//出队
{
    QueueNode p;
    p=q->front->next;
    *node=p->Node;
    q->front->next=p->next;
    if(q->rear==p)       //p将被释放,需要对q->rear进行处理。(不能缺)
        q->rear=q->front;
    free(p);
}
int QueueEmpty(LinkQueue *q)//判断队列是否为空
{
    if(q->rear==q->front)
        return 1;
    else
        return 0;
}
void HierarchyTravel(Tree tree)
{
     LinkQueue q;;
     Init(&q);
     EnQueue(&q,*tree);
     TreeNode node;
     while(!QueueEmpty(&q))
     {
         DeQueue(&q,&node);
         printf("%c\t",node.value);
         if(node.LeftChild)
             EnQueue(&q,*node.LeftChild);
         if(node.RightChild)
             EnQueue(&q,*node.RightChild);
     }
}
int Height(Tree tree)
{
  int high;
  int left_high;
  int right_high;
  if(tree==NULL)
      return 0;
  left_high=Height(tree->LeftChild);
  right_high=Height(tree->RightChild);
  if(left_high>right_high)
        high=left_high+1;
  else
        high=right_high+1;
  return high;
}
int _tmain(int argc, _TCHAR* argv[])
{  
    Tree tree;
    int high;
    printf("输入二叉树节点:");
    tree=CreatTree();
    printf("\n中序遍历:");
    MiddleTravel(tree);
    printf("\n先序遍历:");
    PreTravel(tree);
    printf("\n后序遍历:");
    PostTravel(tree);
    high=Height(tree);
    printf("\n层次遍历:");
    HierarchyTravel(tree);
    printf("\n树高是:%d\n",high);
    system("PAUSE");
    return 0;
}
Paste_Image.png

7、二叉树的非递归遍历代码

#include "stdafx.h"
#include "stdlib.h"
#include <stack>
#include <iostream>
using namespace std;
typedef struct TreeNode{
    char value;
    struct TreeNode * LeftChild;
    struct TreeNode * RightChild;
}TreeNode,*Tree;
Tree CreatTree()
{   
    char value;
    TreeNode * Node;
    scanf("%c",&value);
    if(value=='#')
        Node=NULL;
    else{
        Node=(TreeNode *)malloc(sizeof(TreeNode));
        Node->value=value;
        Node->LeftChild=CreatTree();
        Node->RightChild=CreatTree();
}
    return Node;

}
void PreTravel(Tree tree)
{
   stack<Tree> s;
   while(tree||!s.empty())
   {
       while(tree)
       {
           printf("%c\t",tree->value);
           s.push(tree);
           tree=tree->LeftChild;
       }
       tree=s.top();
       s.pop();
       tree=tree->RightChild;
      
   }
}
void MiddleTravel(Tree tree)
{
   stack<Tree> s;
   while(tree||!s.empty())
   {
       while(tree)
       {
           s.push(tree);
           tree=tree->LeftChild;
       }
       tree=s.top();
      printf("%c\t",tree->value);
      s.pop();
      tree=tree->RightChild;
   }
}

void PostTravel(Tree T)  // 后序遍历的非递归      
{      
    stack<Tree> S;      
    Tree curr = T ;           // 指向当前要检查的节点    
    Tree previsited = NULL;    // 指向前一个被访问的节点    
    while(curr != NULL || !S.empty())  // 栈空时结束      
    {      
        while(curr != NULL)            // 一直向左走直到为空    
        {      
            S.push(curr);      
            curr = curr->LeftChild;      
        }      
        curr = S.top();    
        // 当前节点的右孩子如果为空或者已经被访问,则访问当前节点    
        if(curr->RightChild== NULL || curr->RightChild== previsited)      
        {      
            cout<<curr->value<<"  ";      
            previsited = curr;      
            S.pop();      
            curr = NULL;      
        }      
        else    
            curr = curr->RightChild;      // 否则访问右孩子    
    }      
}  
int _tmain(int argc, _TCHAR* argv[])
{  
    Tree tree;
    int high;
    printf("输入二叉树节点:");
    tree=CreatTree();
   printf("\n中序遍历:");
    MiddleTravel(tree);
    printf("\n先序遍历:");
    PreTravel(tree);
    printf("\n后序遍历:");
    PostTravel(tree);
 /*   high=Height(tree);
    printf("\n层次遍历:");
    HierarchyTravel(tree);
    printf("\n树高是:%d\n",high);*/
    system("PAUSE");
    return 0;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,937评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,503评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,712评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,668评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,677评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,601评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,975评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,637评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,881评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,621评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,710评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,387评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,971评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,947评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,189评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,805评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,449评论 2 342

推荐阅读更多精彩内容

  • 数据结构和算法--二叉树的实现 几种二叉树 1、二叉树 和普通的树相比,二叉树有如下特点: 每个结点最多只有两棵子...
    sunhaiyu阅读 6,422评论 0 14
  • 四、树与二叉树 1. 二叉树的顺序存储结构 二叉树的顺序存储就是用数组存储二叉树。二叉树的每个结点在顺序存储中都有...
    MinoyJet阅读 1,499评论 0 7
  • 树和二叉树 1、树的定义 树(Tree)是由一个 或 多个结点 组成的有限集合T,且满足: ①有且仅有一个称为根的...
    利伊奥克儿阅读 1,347评论 0 1
  • 树的概述 树是一种非常常用的数据结构,树与前面介绍的线性表,栈,队列等线性结构不同,树是一种非线性结构 1.树的定...
    Jack921阅读 4,432评论 1 31
  • 我醒得很早,完完全全地醒透了。 仰面朝天躺在床上,等待着小腹与肠子自己苏醒,一般在脑子开始运转后的十几分钟内,下坠...
    行路Walker阅读 1,321评论 9 51