#include <iostream>
#include <stack>
#include <queue>
using std::cin;
using std::cout;
using std::endl;
using std::stack;
using std::queue;
typedef struct node
{
int data;
struct node *lchild;
struct node *rchild;
}Bnode, *BTree; //创建二叉树 例如输入 1 2 -1 -1 3 -1 -1 创建的是1 2 3二叉树
BTree CreateBinaryTree(BTree &tree)
{
int inputdata;
cin >> inputdata;
if(-1 == inputdata)
{
tree = NULL;
}
else
{
if(!(tree = (Bnode*)malloc(sizeof(Bnode))))
{
cout << "ERROR";
}
tree->data = inputdata; //创建根结点
tree->lchild = CreateBinaryTree(tree->lchild); //创建左子树 递归实现
tree->rchild = CreateBinaryTree(tree->rchild); //创建右子树 递归实现
}
return tree;
} //递归前序遍历
void preorderTraverse(BTree tree)
{
if(tree != NULL)
{
cout << tree->data << " ";
preorderTraverse(tree->lchild);
preorderTraverse(tree->rchild); }
else
{
//cout <<"二叉树为空" << endl;
return;
}
} //非递归前序遍历
//先对根结点入栈,这样根结点最后出栈,保证了在其余层没有完全遍历时s.enpty()为假
//先访问根结点在访问左子树,直到左子树为空后返回其父结点,在访问其同级的右结点
void preorderNotRecursion(BTree tree)
{
stack<BTree> s;
if(!tree)
{
cout << "二叉树为空" << endl;
return;
}
else
{
//借助栈的特性先进后出 实现最底层的到根的逐层输出
while(tree || !s.empty())
{
while(tree)
{
s.push(tree);
cout << tree->data << " ";
tree = tree->lchild;
}
tree = s.top();
s.pop();
tree = tree->rchild;
}
}
} //非递归中序遍历
void inorderNotRecursion(BTree tree)
{
stack<BTree> s;
if(!tree)
{
cout << "二叉树为空" << endl;
return;
}
else
{
while(tree || !s.empty())
{
while(tree)
{
s.push(tree);
tree = tree->lchild;
}
tree = s.top();
cout << tree->data << " ";
s.pop();
tree = tree->rchild;
}
}
} //递归中序遍历
void inorderTraverse(BTree tree)
{
if(tree != NULL)
{
inorderTraverse(tree->lchild);
cout << tree->data << " ";
inorderTraverse(tree->rchild);
}
else
{
//cout <<"二叉树为空" << endl;
return;
}
} //递归后序遍历
void postorderTraverse(BTree tree)
{
if(tree != NULL)
{
postorderTraverse(tree->lchild);
postorderTraverse(tree->rchild);
cout << tree->data << " ";
}
else
{
return;
}
} //非递归后序遍历 画图可以加深印象 入栈出栈
void postorderNotRecursion(BTree tree)
{
/*对于非递归的后序遍历,要保证根结点最后访问,这样对于任意一个结点p应先入栈
如果p没有左子结点和右子结点或者其左子结点和右子结点均已经被访问过,则p结点可
以直接访问,若非上述两种中情况则右子结点和左子结点依次入栈,保证每次出栈时左
子结点在右子结点前被访问
*/
stack<BTree> s;
BTree cur;
BTree pre = NULL;
s.push(tree);
if(!tree)
{
cout << "二叉树为空" << endl;
return;
}
else
{
while(!s.empty())
{
cur = s.top();
if((cur->lchild == NULL && cur->rchild == NULL) || (pre != NULL && (pre == cur->lchild || pre == cur->rchild)))
{
cout << cur->data << " ";
s.pop();
pre = cur;
}
else
{
//顺序很重要!
if(cur->rchild != NULL)
s.push(cur->rchild);
if(cur->lchild != NULL)
{
s.push(cur->lchild);
}
}
}
}
} //按层次遍历二叉树 用队列实现
void levelTraverse(BTree tree)
{
queue<BTree> que;
if(!tree)
{
cout << "二叉树为空" << endl;
return;
}
else
{
while(tree)
{
cout << tree->data << " ";
if(tree->lchild)
que.push(tree->lchild);
if(tree->rchild)
que.push(tree->rchild);
if(que.empty())
break;
tree = que.front();
que.pop();
}
}
} //求二叉树的深度
int depthTree(BTree tree)
{
int dep = 0, depL, depR;
if(!tree)
dep = 0;
else
{
depL = depthTree(tree->lchild);
depR = depthTree(tree->rchild);
dep = 1 + (depL > depR ? depL : depR);
}
return dep;
} //求叶子结点的个数
int sumLeaf(BTree tree)
{
int sum = 0, m, n;
if(tree)
{
//->的优先级高于! 左子树和右子树都为空
if((!tree->lchild) && (!tree->rchild))
sum++;
m = sumLeaf(tree->lchild);
sum += m;
n = sumLeaf(tree->rchild);
sum += n; }
else
return 0;
return sum;
} //度为2的结点数目
int sumDoublePoint(BTree tree)
{
int sum = 0, m, n;
if(tree)
{
if((tree->lchild != NULL) && (tree->rchild != NULL))
sum++;
m = sumDoublePoint(tree->lchild);
sum += m;
n = sumDoublePoint(tree->rchild);
sum += n;
}
else
return 0;
return sum;
} //度为1的结点数目
int sumSinglePoint(BTree tree)
{
int sum = 0;
if(!tree)
return 0;
else
{
if(tree->lchild != NULL && tree->rchild != NULL)
{
sumSinglePoint(tree->lchild);
sumSinglePoint(tree->rchild);
}
if(tree->lchild != NULL && tree->rchild == NULL)
{
sum += 1;
sumSinglePoint(tree->lchild);
}
if(tree->lchild == NULL && tree->rchild != NULL)
{
sum += 1;
sumSinglePoint(tree->rchild);
}
}
return sum;
} //查找树中是否存在要找的元素
//按递归的方式来查找,必须在找的第一时间就输出信息,否则递归的嵌套会使结果掩盖
bool search(BTree tree, int search_num)
{
if(tree)
{
if(tree->data == search_num)
{
cout << tree->data << "==" << search_num << endl;
return true;
}
else
{
if(search(tree->lchild, search_num))
{}
else
search(tree->rchild, search_num);
}
}
else
return false;
} //寻找给定结点的父结点
//测试案例
int main()
{
int search_num;
BTree T;
T = CreateBinaryTree(T); cout <<"递归前序遍历:";
preorderTraverse(T);
cout << endl;
cout <<"非递归前序遍历:";
preorderNotRecursion(T);
cout << endl; cout <<"递归中序遍历:";
inorderTraverse(T);
cout << endl;
cout <<"非递归中序遍历:";
inorderNotRecursion(T);
cout << endl; cout <<"递归后序遍历:";
postorderTraverse(T);
cout << endl;
cout <<"非递归后序遍历:";
postorderNotRecursion(T);
cout << endl; cout <<"按层次遍历二叉树:";
levelTraverse(T);
cout << endl; cout << "树的深度: " << depthTree(T) << endl;
cout << "叶子结点数: " << sumLeaf(T) << endl;
cout << "度为1的结点个数: "<< sumSinglePoint(T) << endl;
cout << "度为2的结点个数: "<< sumDoublePoint(T) << endl; cout << "请输入要查找的元素:";
cin >> search_num;
if(search(T, search_num))
cout << "111" << endl;
else
cout << "000" << endl; return 0;
}

图中所建的二叉树如下所示:

C++实现二叉树的基本操作的更多相关文章

  1. <二叉树的基本操作(有层次遍历)>

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...

  2. C语言实现二叉树的基本操作

    二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...

  3. <二叉树的基本操作>

    #include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...

  4. 实现二叉树的基本操作(Java版)

    近期研究了一下二叉树,试着用Java语言实现了二叉树的基本操作,下面分享一下实现代码: package com.sf.test; import java.util.ArrayDeque; import ...

  5. c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)

    #include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...

  6. 二叉树的基本操作(C语言版)

    今天走进数据结构之二叉树 二叉树的基本操作(C 语言版) 1 二叉树的定义 二叉树的图长这样: 二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆.二叉树是链式存储结构,用的是二叉 ...

  7. 二叉树的基本操作(含Huffman树)

    大二时候写的烂代码,翻出来复习复习(o(╯□╰)o). 代码: #include <stdio.h> #include <stdlib.h> #define Max_Size ...

  8. 二叉树的基本操作(C)

    实现二叉树的创建(先序).递归及非递归的先.中.后序遍历 请按先序遍历输入二叉树元素(每个结点一个字符,空结点为'='): ABD==E==CF==G== 先序递归遍历: A B D E C F G ...

  9. Java 二叉树一些基本操作

    求二叉树中节点个数: /*1. 求二叉树中的节点个数 递归解法: (1)如果二叉树为空,节点个数为0 (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1 */ pu ...

随机推荐

  1. SqlDbType与DbType这间的转换关系

    SqlDbType => DbType SqlDbType.BigInt DbType.Int64 SqlDbType.Binary DbType.Binary SqlDbType.Bit Db ...

  2. redis的5种数据结构的简介

    5种数据结构 1.字符串 Redis 字符串是一个字节序列.在 Redis 中字符串是二进制安全的,这意味着它们没有任何特殊终端字符来确定长度,所以可以存储任何长度为 512 兆的字符串. 示例 12 ...

  3. LNMP优化

        LNMP优化 LNMP优化从系统安全,系统资源占用率,及web服务并发负载这三个方面体现,并   且主要体现在web服务并发负载这一方面.     1:首先进行linux优化加固  Linux ...

  4. linux syslog详解

    linux syslog详解 分三部分 一.syslog协议介绍 二.syslog函数 三.linux syslog配置   一.syslog协议介绍 1.介绍 在Unix类操作系统上,syslog广 ...

  5. struts2 result的type属性

    目前只使用过以下3种,都是直接跳转到另一个action  chain: 写法:<result name="success" type="chain"> ...

  6. 抽空通过简书网学习了一下console,感觉高大上!

    抽空看了一下简书中关于console的文章,为了便于自己今后查看,自己写了一遍!原文地址:http://www.jianshu.com/p/f961e1a03a56 测试代码在最下面 1.consol ...

  7. Array.prototype.sort()

    sort() 方法对数组的元素做原地的排序,并返回这个数组.默认按照字符串的Unicode码位点(code point)排序. 语法 arr.sort([compareFunction]) 参数 co ...

  8. JasperReport使用心得

    1. JasperReport 报表文件视图化生成工具iReport. iReport做为一个生成JasperReport的视图工具,和我们是使用的大多数报表创建工具没有太大的差别,都是拖控件,搭出报 ...

  9. 《APUE》读书笔记第十一章-线程

    本章主要介绍了线程,了解如何使用多线程在单进程环境中来执行多任务.由于多个线程共享其进程空间,所以必须采用同步的机制来保护数据的一致性. 一.线程的概念 典型的Unix系统都可以看成只有一个控制线程, ...

  10. Core Data数据持久性存储基础教程-备用

    摘要 就像我一直说的,Core Data是iOS编程,乃至Mac编程中使用持久性数据存储的最佳方式,本质上来说,Core Data使用的就是SQLite,但是通过一系列特性避免了使用SQL的一些列的麻 ...