基本二叉树操作

二叉树的基本操作 二叉树的图长这样:二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆。二叉树是链式存储结构,用的是二叉链,本质上是链表。二叉树通常以结构体的形式定义,如下,结构体内容包括三部分:本节点所存储的值、左孩子节点的指针、右孩子节点的指针。当然,我们也可以为我们的的树节点结构体重新定义一下名字,使用 C 语言中的 typedef 方法就可以了。 阅读详情

    涉及的内容包括递归前序,中序和后序遍历;非递归前中后序遍历;二叉树的层次遍历;求二叉树的深度;求二叉树的结点数。

    其中二叉树的非递归遍历都是用的C++中的stack和set容器,方法比较笨(同时想到的另一个方法是修改二叉树的数据结构,在节点的结构体中增加一个标志位,在遍历的时候当节点输出后设置标志位为访问过,其效果与利用set容器一样,但相对方便些)。二叉树的层次遍历用到了vector可自增长的特性,而且使用下标取值的方法,而用迭代器iterator就会出现问题,因为push_back()操作之后原来容器中的迭代器就会失效。求二叉树深度和结点数的程序都是用到了递归的方法。

    创建二叉树是用的先序遍历次序的方法,其中空结点用字符'#'来表示,而这种标记方法也给后来其他二叉树的操作带来了方便,主要是可以确定一些循环的结束条件。在创建二叉树的时候需要为新的结点提前申请好空间否则就会将指针指向NULL。

#include <iostream>
#include <stack>
#include <vector>
#include <set>

using namespace std;

typedef struct TreeNode
{
        char data;
        struct TreeNode *lchild;
        struct TreeNode *rchild;
}TreeNode, *pTreeNode;   //

//  创建二叉树(先序) 
//pTreeNode CreateBinaryTree(pTreeNode root)
int CreateBinaryTree(pTreeNode root)
{
          char ch;
          //TreeNode root;
          cout<<"Please input the node:"<<endl;
          //root=new TreeNode;
          cin>>ch;
          if(ch=='#')
              //return root->data=ch;
          {
              root->data=ch;
              //return root;
              return 0;
          }
          else
          {
              root->data=ch;
              CreateBinaryTree(root->lchild=new TreeNode);
              CreateBinaryTree(root->rchild=new TreeNode);
          }
          
          //return root;
          return 0;
}

//  先序递归遍历
int PreOrderTraverse(pTreeNode root)
{
    if(root->data=='#')
        return 0;
    cout<<root->data<<endl;
    PreOrderTraverse(root->lchild);
    PreOrderTraverse(root->rchild);
    
    return 0;
}
//  中序递归遍历 
int InOrderTraverse(pTreeNode root)
{
    if(root->data=='#')
        return 0;
    InOrderTraverse(root->lchild);
    cout<<root->data<<endl;
    InOrderTraverse(root->rchild);
    
    return 0;
}
//  后序递归遍历 
int PostOrderTraverse(pTreeNode root)
{
    if(root->data=='#')
        return 0;
    PostOrderTraverse(root->lchild);
    PostOrderTraverse(root->rchild);
    cout<<root->data<<endl;
    
    return 0;
}

//  前序非递归遍历
int PreNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    set<int> Array;
    S.push(root);
    cout<<S.top()->data<<endl;
    Array.insert(S.top()->data);
    //while(!S.empty())
    for(;;)
    {
                     if(root->lchild->data!='#' && Array.find(root->lchild->data)==Array.end())
                     {
                                           S.push(root->lchild);
                                           Array.insert(S.top()->data);
                                           cout<<S.top()->data<<endl;
                                           root=root->lchild; //
                     }
                     else if(root->rchild->data!='#' && Array.find(root->rchild->data)==Array.end())
                     {
                                           S.push(root->rchild);
                                           Array.insert(S.top()->data);
                                           cout<<S.top()->data<<endl;
                                           root=root->rchild;
                     }
                     else
                     {
                          S.pop();
                          //if(S.top()==NULL)
                          //    break;
                          //else
                          if(S.empty())
                              break;
                          else
                          root=S.top();
                     } 
    }
    
    return 0;
} 
//  中序非递归遍历 
int InNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    set<int> Array;
    S.push(root);
    for(;;)
    {
           if(root->lchild->data!='#' && Array.find(root->lchild->data)==Array.end())
           {
                                      S.push(root->lchild);
                                      root=root->lchild;
           }
           else
           {
               if(Array.find(root->data)==Array.end())
               {
                           cout<<S.top()->data<<endl;
                           Array.insert(S.top()->data);
               }
               if(root->rchild->data!='#' && Array.find(root->rchild->data)==Array.end())
               {
                                          S.push(root->rchild);
                                          root=root->rchild;
               }    
               else
               {
                   S.pop();
                   if(S.empty())
                       break;
                   root=S.top();
               }
           }
    }
    
    return 0;
} 
//   后序非递归遍历
int PostNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    set<int> Array;
    S.push(root);
    for(;;)
    {
           if(root->lchild->data!='#' && Array.find(root->lchild->data)==Array.end())
           {
                                      S.push(root->lchild);
                                      root=root->lchild; //
           }
           else
           {
               if(root->rchild->data!='#' && Array.find(root->rchild->data)==Array.end())
               {
                                          S.push(root->rchild);
                                          root=root->rchild;
               }
               else
               {
                   cout<<S.top()->data<<endl;
                   Array.insert(S.top()->data);
                   S.pop();
                   if(S.empty())
                       break;
                   root=S.top();
               }
           }
    }
    
    return 0;
} 

int HierarchicalTraverse(pTreeNode root)
{
    int i=0;
    vector<pTreeNode> V;
    V.push_back(root);
    for(;;)
    {
           if(V[i]->lchild->data!='#')
               V.push_back(V[i]->lchild);
           if(V[i]->rchild->data!='#')
               V.push_back(V[i]->rchild);
           i++;
           if(i==V.end()-V.begin()) // 通过标识将迭代器转化为下标 
               break;
    }
    vector<pTreeNode>::iterator j;
    for(j=V.begin();j!=V.end();j++)
        cout<<(*j)->data<<endl;
        
    return 0; 
}
/*
int HierarchicalTraverse(pTreeNode root)
{
    vector<pTreeNode> V;
    V.push_back(root);
    vector<pTreeNode>::iterator i=V.begin();
    for(;;)
    {
           if((*i)->lchild->data!='#')
               V.push_back((*i)->lchild); 任何改变vector长度的操作都会使已存在的迭代器失效。
                                          例如,在调用push_back之后,就不能再信赖指向vector的迭代器的值了。
           if((*i)->rchild->data!='#')
               V.push_back((*i)->rchild);
           i++;
           if(i==V.end()) 
               break;
    }
    for(i=V.begin();i!=V.end();i++)
        cout<<(*i)->data<<endl;
        
    return 0; 
}
*/
int TreeDepth(pTreeNode root)
{
    int depth=0;
    if(root->data=='#')
        return depth;
    if(root->lchild->data=='#' && root->rchild->data=='#')
        depth=1;
    else
    {
        int l=TreeDepth(root->lchild);
        int r=TreeDepth(root->rchild);
        depth=1+(l>r?l:r);  // ?:运算符优先级最低 
    }
    
    return depth;
} 

int NodeCounts(pTreeNode root)
{
    int count=0;
    if(root->data=='#')
        return count;
    if(root->lchild->data=='#' && root->rchild->data=='#')
        count=1;
    else
        count=count+NodeCounts(root->lchild)+NodeCounts(root->rchild)+1;
    
    return count;
} 

int main()
{
    pTreeNode r=new TreeNode;
    //r=CreateBinaryTree(r);
    CreateBinaryTree(r);
    cout<<"After Creation:"<<endl;
    
    cout<<"PreOrderTraverse:"<<endl;
    PreOrderTraverse(r);
    cout<<"InOrderTraverse:"<<endl;
    InOrderTraverse(r);
    cout<<"PostOrderTraverse:"<<endl;
    PostOrderTraverse(r);
    
    cout<<"PreNonrecursive"<<endl;
    PreNonrecursive(r);
    cout<<"InNonrecursive"<<endl;
    InNonrecursive(r);
    cout<<"PostNonrecursive"<<endl;
    PostNonrecursive(r);
    
    cout<<"层次遍历二叉树"<<endl;
    HierarchicalTraverse(r);
    
    cout<<"二叉树深度:"<<TreeDepth(r)<<endl;
    
    cout<<"二叉树结点数:"<<NodeCounts(r)<<endl;
        
    return 0;
}


创建如下图所示二叉树:

所需要的输入为:124##58###36##7##

部分结果为:


    参考了一下别人的代码,重新做了一下二叉树的先序和中序遍历,其没有用到set容器来保存已经遍历过的结点值,而是直接在遍历过程中将遍历过的节点出栈,更好地实现了迭代的方法,其对栈有一部分的操作开始还以为是写错了,后来才明白了其中的含义,中序与前序的思路基本一样,后序稍微有些复杂需要保存之前的变量,代码如下:

//  前序非递归遍历   (将输出结点值后的结点出栈) 
int PreNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    pTreeNode p=root;
    S.push(p);
    cout<<p->data<<endl;
    p=p->lchild;
    
    while(!S.empty() || p->data!='#')  // 条件判断处需注意,因在根节点处遍历完根节点后根节点出栈则栈为空,但此时还有右孩子非空等待入栈
    {
                     if(p->data!='#')
                     {
                                     S.push(p);
                                     cout<<p->data<<endl;
                                     p=p->lchild;
                     }
                     else
                     {
                         p=S.top();
                         p=p->rchild;
                         S.pop();
                     }
    }
    
    return 0;
}
    相比于前序非递归遍历,中序遍历只是改变了输出节点语句的位置。

//  中序非递归遍历 
int InNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    pTreeNode p=root;
    S.push(p);
    p=p->lchild;
    
    while(!S.empty() || p->data!='#')
    {
                     if(p->data!='#')
                     {
                                     S.push(p);
                                     p=p->lchild;
                     }
                     else
                     {
                         p=S.top();
                         cout<<p->data<<endl;
                         p=p->rchild;
                         S.pop();
                     }
    }
    
    return 0;
}

    后序遍历中,我开始也是模仿前序和中序遍历的方式,然后在结合后序遍历的特点做一下修正,用到的方法就是给出一些二叉树的特殊的情况,比如如下的形式:

     

    然后不断地调整代码的写法,暂时还没找到一个想法可以很清晰地说明代码就该这么写,在写的时候只知道有两点可以利用:1,满足二叉树后序遍历的规则,也就是左右根的顺序。2,可以利用栈的操作来完成回溯。

    在先序和中序遍历中,可以在遍历完节点后直接处理节点,而在后序遍历中却需要保存节点,直到符合要求的时候才做处理(主要是pop()操作),为保存父子节点我定义了两个指针,但是按照原来的想法还是不能够完成后序遍历,因为按照原来的操作在回溯后无法判断此节点右子树是否遍历过,则会造成死循环,为此需要有一个标志位来表明此右孩子已经遍历过,这就涉及到最开始用到的两个想法:1,利用set容器保存已遍历节点的值。2,修改数据结构设置标志位字段。但是想摆脱这样的算法又该如何呢?

    后来我还是看了上篇的文章,但是联系到自己设置的数据结构则会修改已经建立好的树,其思想是:将遍历过的节点置为空,在本文中即node->data='#'。这样在条件判断时就可以加上一句判断是否遍历过的语句。但是这样就完全破坏了树的结构,让后续的操作无法进行,虽然可以正确的得到后序遍历的结果。代码如下:这一部分写错了,是将遍历过的节点用另一个指向节点的指针记录下来,然后在回溯的时候可以判断回溯节点的右子树是否已经遍历过。(其实置空也是可以的,不过破坏了树结构,如下)

int PostNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    pTreeNode p=root, q=NULL;
    S.push(p);
    p=p->lchild;
    
    while(!S.empty())
    {
                     if(p->data!='#')
                     {
                                     S.push(p);
                                     q=p;       // q记录上一个节点
                                     p=p->lchild;
                     }
                     else
                     {
                         p=q->rchild;
                         if(p->data=='#')
                         {
                                         cout<<q->data<<endl;
                                         q->data='#';         // 只增加这一句便可完成置为空的操作
                                         S.pop();
                                         if(!S.empty())
                                             q=S.top();
                                         else
                                             break;
                         }
                     }
    }
    
    return 0;
}
会出现如下的错误:


树的结构被破坏。

但是在参考文章中同样的思想却可以顺利地进行其余的操作,这究竟是为什么呢?原来在建立和遍历树的时候,作者用到了不同的数据结构。用的是相同的结构,是算法不同。

int PostNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    pTreeNode p=root, q=NULL;
    S.push(p);
    p=p->lchild;
    
    while(!S.empty())
    {
                     if(p->data!='#')
                     {
                                     S.push(p);
                                     p=p->lchild;
                     }
                     else
                     {
                         p=S.top();
                         if(p->rchild->data=='#' || p->rchild==q)
                         {
                                                 cout<<p->data<<endl;
                                                 q=p;    // 记录遍历后的节点
                                                 S.pop();
                                                 p=new TreeNode;    // 因为在树的节点建立过程中是利用 '#'来表示空,但是不能在原节点上操作,故新建节点
                                                 p->data='#';       // 主要的目的是避免重复入栈操作
                         }
                         else
                             p=p->rchild;
                     }
    }
    
    return 0;
}

可以在建树的时候,将代码:

if(ch=='#')

{

root->data=ch;

return 0;

}

改为

if(ch=='#')

{

root=NULL;

return 0;

}

此时其他的代码也需要修改,这样所有的判断空节点的语句 p->data=='#'就将改为p==NULL,这样更符合平常的习惯。

上文写错了,犯了最基本的错误----函数传参赋值的错误,因为CreateBinaryTree()的参数是pTreeNode类型(指针类型),在函数中直接修改参数的值是没有用处的,因为在函数内部用了一个在栈中的临时变量代替参数,函数结束后变量释放,参数值是没有被修改的,所以为了达到目的需要传递参数的地址,在这里就是指针的地址,也就是指向指针的指针,这样才能满足为指针符空值,修改如下:

//  创建二叉树(先序) 
//pTreeNode CreateBinaryTree(pTreeNode root)
int CreateBinaryTree(pTreeNode *root)
{
          char ch;
          //TreeNode root;
          cout<<"Please input the node:"<<endl;
          //root=new TreeNode;
          cin>>ch;
          if(ch=='#')
              //return root->data=ch;
          {
              *root=NULL;
              //return root;
              return 0;
          }
          else
          {
              (*root)->data=ch;
              CreateBinaryTree(&((*root)->lchild=new TreeNode));
              CreateBinaryTree(&((*root)->rchild=new TreeNode));
          }
          
          //return root;
          return 0;
}
其他函数不需要做改正,只是在需要判断空节点的时候将p->data=='#'改为p==NULL即可,修改后序遍历为:

int PostNonrecursive(pTreeNode root)
{
    stack<pTreeNode> S;
    pTreeNode p=root, q=NULL;
    S.push(p);
    p=p->lchild;
    
    while(!S.empty())
    {
                     if(p != NULL)
                     {
                                     S.push(p);
                                     p=p->lchild;
                     }
                     else
                     {
                         p=S.top();
                         if(p->rchild == NULL || p->rchild==q)
                         {
                                                 cout<<p->data<<endl;
                                                 q=p;
                                                 S.pop();
                                                 p=NULL;
                         }
                         else
                             p=p->rchild;
                     }
    }
    
    return 0;
}

二叉树的基本操作 C++代码实现 首先定义节点typedef struct BTree { int value; struct BTree *lchild; struct BTree *rchild; }BTree;前序递归建立二叉树/* **num 前序序列 **index 下标 */ BTree *CreateBTree(BTree *node,int *num,int& index) { 阅读详情

相关推荐

论文阅读《Eigen-GNN: A Graph Structure Preserving Plug-in for GNNs》

好久没看论文了,感觉好生疏 关于这篇文章的大致脉络,这篇文章已经介绍过了。

且视他人之疑目如盏盏鬼火,大胆地去走你的夜路 462

二叉树基本操作

二叉树的先序,中序,后序遍历的递归与非递归,二叉排序树的建立,添加,删除,满二叉树,完全二叉树的判断

青耕_的博客 1901

实现高精度卷积混响--MATLAB仿真篇

一、前言 之前在STM32F407上现实了直播声卡,实现的经典Schroeder混响模型和Moorer混响模型,得到不错效果。后来得知卷积混响最为真实地表现空间的特性,所以也就尝试在MCU上实现一个高精度的卷积混响(卷积点数为32768),目前MCU出来的混响效果算得上一流水准,本人也在计划在ADI的21489或者SC584上更高精度的卷积混响。 二、卷积方式 1、conv1是使用MATLAB自带卷积函数conv 2、conv2和conv3是改进后卷积过程,具有减少运算量特点,方便嵌入式移植 clear;

Six44的博客 5079

数据结构 - 线索树

当然,我们肯定需要借助结点的指针域来保存直接前驱和直接后继的地址。其实,在上图的普通二叉树中(以中序遍历得到的序列),部分结点(指针域不为空的结点)是可以找到其直接前驱或后继的,比如结点 E 的左孩子 G 就是结点 E 的直接前驱;结点 A 的右孩子 C 就是结点 A 的直接后继。但部分结点(指针域为空)是行不通的,比如结点 G 的直接后继是 E,直接前驱是 B,但在二叉树中却不能得出这样的结论。怎么办呢?

gghhb12的博客 2238

基于大模型的围术期谵妄防控系统研究报告

围术期谵妄是一种急性脑功能障碍综合征,通常发生在手术前后一段时间内。患者会出现意识障碍、注意力不集中、认知功能紊乱、睡眠 - 觉醒周期失调等症状,严重者甚至会出现幻觉、妄想和攻击行为 。这种病症不仅会给患者自身带来极大的痛苦,还会对其术后康复产生严重的负面影响。从患者角度来看,围术期谵妄会显著延长患者的住院时间,增加患者的医疗费用负担。有研究表明,发生谵妄的患者住院时间平均比未发生者延长 2 - 3 天。长时间的住院不仅会影响患者的生活质量,还可能导致患者错过最佳的康复时机,影响身体机能的恢复。同时,谵妄还

嵌入式毕设/课设资料清单(速查手册·文档模板·题库,持续更新)→ 见最新文章 1071

消费级显卡跑大模型:RTX 3060 12G 部署 70 亿参数 AI 编程助手的优化实战

本文详细介绍了如何在消费级显卡RTX 3060 12G上,通过量化、投机解码和分页KV-Cache等核心优化技术,成功部署并流畅运行70亿参数的CodeLlama-7B编程助手。文章提供了从环境配置、模型准备到参数调优的完整实战笔记,实测显存占用降至7.3GB,生成速度达21.7 token/秒,为开发者和技术爱好者提供了可行的本地AI部署方案。

weixin_29053067的博客 1259

【数据结构】3——线索二叉树

线索二叉树

qq_43507078的博客 803

uniapp - 微信小程序接入官方人脸识别认证详细流程及示例源码,Uniapp微信小程序项目集成官方提供的人脸识别身份验证插件接口(多种示例:人脸核验、身份证件与人脸是否匹配、是否活体、实名认证等)

uni-app微信小程序人脸识别认证,使用uniapp开发微信小程序的人脸采集功能/人脸识别功能,uniapp vue3微信小程序活体人脸识别,Uni-app微信小程序实名认证,uniApp微信小程序人脸认证,UniApp的微信小程序实名认证与人脸识别系统开发,人脸核身微信小程序uni-app接入流程,wx.startFacialRecognitionVerify,uniapp开发微信小程序-人脸采集功能、微信人脸识别实名认证集成指南,识别失败,人脸识别接口怎么调用,前后端完整示例代码demo,人脸检测功能

🏆 前端领域优质创作者 3284

数据结构——二叉树 |关于线索二叉树的理解和实现

1

weixin_46096297的博客 581

Python爬虫实战:百度贴吧帖子与评论抓取全攻略(附舆情分析技巧)

基础配置# 要爬取的贴吧名称(替换成自己需要的,比如“XX手游吧”)TIEBA_NAME = "XX手游"# 分页参数(每页50条帖子,可根据需求调整)PAGE_NUM = 3 # 爬取前3页帖子,共150条# 请求头(从浏览器复制自己的,更真实)Win64;

专注于Python爬虫开发,分享爬虫技巧、项目实战与反爬经验,使用Scrapy、BeautifulSoup等工具,解决数据抓取难题。 2388

100:vue+cesium: 加载glb文件,随机位置加载2000架飞机

本示例在 Vue + cesium 项目中随机位置加载2000架飞机,飞机是glb文件,每个大小为571kb。这个示例属于性能优化的范畴内,通常如果用entity加载glb只能显示几个飞机,这里采用primitive的方法来加载。直接复制下面的 vue+cesium源代码,操作2分钟即可运行实现效果.

大剑师兰特的GIS世界 706

数据结构之线索二叉树

为啥需要线索二叉树 我想正如程序猿发觉单链表并不总能满足他们设计的程序某些要求的时候,发明了双向链表来弥补一样,线索二叉树也是在需求中被创造的!   那普通的二叉树到底有什么缺陷让我们发指呢? 一,浪费空间 二,浪费时间  哪种遍历方式更适合节省"^"所浪费的空间 如上图(可以节省空间的节点有红色表示) 前序:ABDHIECFG 中序:HDIBEAFCG 后序:HIDEBFGCA ...

qq_35654259的博客 335

【linux】linux 出现一个网卡绑定多个ip怎么处理

我的原因是我使用了dhcp,这个会自动分配ip, 将 BOOTPROTO 参数由 dhcp 改为 static,并移除或注释掉与动态分配地址 10.0.2.15 相关的配置行(如果存在)。执行后,您可以再次使用 ip -4 a 或 ifconfig 命令确认 IP 地址已被移除。输出可以看出,您的虚拟机(k8s003)中存在一个名为 enp0s3 的网卡绑定了多个 IPv4 地址。对于某些 Linux 发行版(如 Ubuntu、Debian),您可能需要编辑网络接口的配置文件来移除多余的 IP 地址。

九师兄 297

二叉树的类型定义与基本操作

二叉树的类型定义与基本操作 树结构是一类重要的非线性数据结构,在客观世界中广泛存在。树在计算机领域中也得到了广泛的应用,尤以二叉树最为常用。本文重点讨论二叉树的基本操作。 1. 二叉树的类型定义 二叉树通常由三个域组成:数据域、左孩子指针域和右孩子指针域。 其类型定义为: typedef struct BiNode { char data; // 数据域 struct BiNode* lchild, * rchild; // 左右孩子指针域 }Bi

qq_45801780的博客 5475

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

C++ 二叉树的基本操作

一:目的 用C++实现二叉树的基本操作,建立和遍历; 二:介绍 在计算机科学中,二叉树是每个节点最多有两个子树的树结构。通常子树被称作“左子树”(left subtree)和“右子树”(right subtree)。二叉树常被用于实现二叉查找树和二叉堆。 二叉树的遍历方式有三种,前序遍历,中序遍历,后序遍历。 它的前序遍历顺序为:ABDGHCEIF(规则是先是

nichengwuxiao的博客 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

【数据结构】二叉树的存储与基本操作的实现

二叉树的存储结构分为:顺序存储和类似于链表的链式存储这里博主讲一下链式存储二叉树的链式存储是通过一个一个的节点引用起来的,常见的表示方式有二叉和三叉表示方式二叉表示: 三叉表示: 这里博主主要讲解一下孩子表示法在学习二叉树的基本操作前,需先要创建一棵二叉树,然后才能学习其相关的基本操作。由于现在大家对二叉树结构掌握还不够深入,为了降低大家学习成本,此处手动快速创建一棵简单的二叉树。 创建如下: 注意:上述代码并不是创建二叉树的方式,真正创建二叉树方式后序详解重点讲解在我们对二叉树进行基本操作之前,我们的先来

m0_71731682的博客 4200

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

四、二叉树基本操作

有一个特殊的节点:根节点,根节点没有前驱节点。除根节点外,其余节点被分成 M(M > 0)个互不相交的集合,其中每一个集合又是一颗与树类似的子树。树是递归定义的。

kt_su的博客 641

【数据结构】实现二叉树的基本操作

二叉树的前序、中序、后序以及层序遍历,获取节点个数,判断是否为完全二叉树等~

qq_53869058的博客 4785

实验五 二叉树基本操作的编程实现

二叉树基本操作的编程实现(2学时,验证型),掌握二叉树的建立、遍历、插入、删除等基本操作的编程实现,也可以进一步编程实现查找等操作,存储结构主要采用顺序或链接结构。二叉树由根节点、左子树和右子树组成,而左子树和右子树也是一棵二叉树,它们的定义与原二叉树的定义相同,因此可以使用递归的方式来定义二叉树。=',') //输入数据不为逗号,表示不为虚结点,否则为虚结点。case 3:printf("二叉树中序遍历结果为:\n");case 4:printf("二叉树后序遍历结果为:\n");

Htw18705081160的博客 1583

Java 实现二叉树的基本操作

聚焦二叉树基本操作,包括获取节点数、叶子节点数、第K层节点数、树的深度、检测特定值是否存在以及判断是否为完全二叉树。代码,图解相结合帮助理解 整条街都是恋爱的人    我独自走在暖风的夜 ——寂寞的季节 DT

LL_break的博客 1033

二叉树的一些基本操作

遍历二叉树与二叉树的简单题型

m0_74380143的博客 301
上一篇: 2012.4.24百度联盟搜索部电话面试
下一篇: Oracle数据库用户及表的操作
ProfessionalEngineer
博客等级 码龄19年 295粉丝 154原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值