C++实现二叉树的基本操作
#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++实现二叉树的基本操作的更多相关文章
- <二叉树的基本操作(有层次遍历)>
#include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...
- C语言实现二叉树的基本操作
二叉树是一种非常重要的数据结构.本文总结了二叉树的常见操作:二叉树的构建,查找,删除,二叉树的遍历(包括前序遍历.中序遍历.后序遍历.层次遍历),二叉搜索树的构造等. 1. 二叉树的构建 二叉树的基本 ...
- <二叉树的基本操作>
#include<stdio.h> #include<stdlib.h> #include<string.h> #define num 100 #define OK ...
- 实现二叉树的基本操作(Java版)
近期研究了一下二叉树,试着用Java语言实现了二叉树的基本操作,下面分享一下实现代码: package com.sf.test; import java.util.ArrayDeque; import ...
- c语言描述的二叉树的基本操作(层序遍历,递归,非递归遍历)
#include<stdio.h> #include<stdlib.h> #define OK 1 #define ERROR 0 #define TRUE 1 #define ...
- 二叉树的基本操作(C语言版)
今天走进数据结构之二叉树 二叉树的基本操作(C 语言版) 1 二叉树的定义 二叉树的图长这样: 二叉树是每个结点最多有两个子树的树结构,常被用于实现二叉查找树和二叉堆.二叉树是链式存储结构,用的是二叉 ...
- 二叉树的基本操作(含Huffman树)
大二时候写的烂代码,翻出来复习复习(o(╯□╰)o). 代码: #include <stdio.h> #include <stdlib.h> #define Max_Size ...
- 二叉树的基本操作(C)
实现二叉树的创建(先序).递归及非递归的先.中.后序遍历 请按先序遍历输入二叉树元素(每个结点一个字符,空结点为'='): ABD==E==CF==G== 先序递归遍历: A B D E C F G ...
- Java 二叉树一些基本操作
求二叉树中节点个数: /*1. 求二叉树中的节点个数 递归解法: (1)如果二叉树为空,节点个数为0 (2)如果二叉树不为空,二叉树节点个数 = 左子树节点个数 + 右子树节点个数 + 1 */ pu ...
随机推荐
- jquery easyui-datagrid 如何清空数据
//清空原有数据 方法1: var item = $('#filegrid').datagrid('getRows'); if (item) { ; i >= ; i--) { var in ...
- 激光推送SSL问题
1.导出极光推送服务器上的证书,导出后文件扩展名是.cer. 下载极光推送服务器上的证书 2.利用极光推送服务器的证书文件,创建客户端密钥库,密钥库的文件扩展名是.jks Dos command: ...
- iOS import导入pod第三方库不提示问题
pod 导入第三方库后,使用import 不提示第三方库头文件. 解决办法: 选择target -> BuildSettings -> search Paths 下的 User Heade ...
- struts2 MessageStoreInterceptor 拦截器的使用
MessageStoreInterceptor 拦截器可以把和该 Action 相关的 messages, errors 和 field errors(下称 "消息") 保存到 s ...
- JAVA 对象引用,以及对象赋值(转)
原文链接:http://zwmf.iteye.com/blog/1738574 关键字: java对象 引用 Java对象及其引用 关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里 ...
- Manasa and Stones
from __future__ import print_function def main(): t = int(raw_input()) for _ in range(t): n = int(ra ...
- jquery实现当前页面编辑
实现效果 代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- MySql增加字段、删除字段、修改字段
MySql增加字段.删除字段.修改字段名称.修改字段类型 1.增加一个字段 alter table user add COLUMN new1 VARCHAR(20) DEFAULT NULL; / ...
- InnoSetup XML操作函数
用于InnoSetup 5 以上.对XML文件的操作,简化InnoSetup XML访问过程. 1. [代码]InnoSetup 5 脚本 { ======================== ...
- 图解SSL/TLS协议(转)
本周,CloudFlare宣布,开始提供Keyless服务,即你把网站放到它们的CDN上,不用提供自己的私钥,也能使用SSL加密链接. 我看了CloudFlare的说明(这里和这里),突然意识到这是绝 ...