#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. 《第一行代码》学习笔记18-广播接收器Broadcast_Receiver(1)

    1.网络通信原理,在一个IP网络范围内最大的IP地址是被保留作为广播地址来使用的.某个网络的IP 范围是192.168.0.XXX, 子网掩码是255.255.255.0,则该网络的广播地址是192. ...

  2. C# Winform中DataGridView的DataGridViewCheckBoxColumn CheckBox选中判断

    1.DataGridViewCheckBoxColumn CheckBox是否选中 在判断DataGridView中CheckBox选中列的时候,用DataGridViewRow.Cells[0].F ...

  3. JS创建对象的七大模式

    1. 工厂模式 function createPerson(name, age, job){var o = new Object();o.name = name;o.age = age;o.job = ...

  4. DoctrineMigrationsBundle

    数据库迁移特征是数据库抽象层的扩展,允许你用编程的方式,安全.方便.标准化实现数据库结构的更新. 安装 首先使用composer安装 $ composer require doctrine/doctr ...

  5. python 学习(三)

    按照上次python 学习(二)的思路,第一步要实现从一个网站的页面上自动获取指定列表中的信息.折腾数日,得到一段可以正常运行的代码,如下: #web2.py import re import url ...

  6. WinPython安装问题(pyzmq问题导致)

    最近yvivid安装WinPython-32bit-3.4.4.1, 安装后,运行spyder运行时出现如下错误, Traceback (most recent call last): File &q ...

  7. HDU 5417 Victor and Machine

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5417 Problem Description Victor has a machine. When t ...

  8. JavaWeb学习笔记--HttpServletRequest、HttpServletResponse对象常用方法

    HttpServletRequest HttpSession session = request.getSession(true); //获取会话对象 Cookie[] cookies = reque ...

  9. iotop

    iotop命令是专门显示硬盘IO的命令,界面风格类似top命令.这个命令只有在kernelv2.6.20及以后的版本中才有.   1.直接yum安装,rh6的光盘里有包. yum install io ...

  10. Prime Palindrome Golf

    Prime Palindrome Golf Do you know how to play Prime Palindrome Golf? You are given a number and your ...