二叉搜索树
2015-10-17 11:01
399 查看
二叉搜索树
二叉搜索树:是一颗二叉树但是其根节点的只要比左节点大比右节点小。二叉树的遍历
给定一棵树对其进行访问1.先序遍历
(1). 访问根节点
(2). 先序遍历其左子树
(3).先序遍历其右子树
其上图二叉树先序遍历的结果为:ABDFECGHI
其代码实现为:
void preOrderTraver(BinTree root) { if (!root) { //visit(root); cout << root->data << endl; preOrderTraver(root->left); preOrderTraver(root->right); } }
上述代码为递归实现,但是我们可以非递归实现:
因为二叉树的先序遍历,总是先访问其根节点然后在遍历其左子树,最后才是右子树,因此我们可以创建一个堆栈来模拟这个过程。
//先序遍历 void preOrderTraver(BinTree root) { std::stack<BinTree*> st; //创建一个堆栈用来存储二叉树的节点 BinTree node = root; while(node || !st.empty()) { while(node) { std::cout << node->data << " "; //访问其根节点 st.push(node); //把左子树压入堆栈 node = node->left; //一直遍历其左子树直到为空 } if(!st.empty()) { node = st.top(); st.pop(); node = node->right;//遍历其右子树 } } std::cout << std::endl; }
2.中序遍历
(1). 先序遍历其左子树
(2). 访问根节点
(3).先序遍历其右子树
其上图二叉树先序遍历的结果为:DBEFAGHCI
其递归代码为:
//中序遍历 void inOrderTraver(BinTree root) { if (!root) { inOrderTraver(root->left); std::cout << root->data << " "; //visit(root->data); inOrderTraver(root->right); } }
非递归实现为
void inOrderTraver(BinTree root) { std::stack<BinTree> st; auto node = root; while(node || !st.empty()) { while(node) { st.push(node); node=node->left; } if(!st.empty()) { node =st.top(); st.pop(); std::cout << node->data << " "; node = node->right; } } std::cout << std::endl; }
3.后序遍历
(1). 先序遍历其左子树
(2).先序遍历其右子树
(3). 访问根节点
void postOrderTraver(BinTree root) { if (!root) { postOrderTraver(root->left); postOrderTraver(root->right); cout << root->data << " "; //visit(root); } }
4.层次遍历
//层次遍历 void levelOrderTraver(BinTree root) { std::queue<BinTree> qu; auto node = root; if(!root) return ; qu.push(root); while(!qu.empty()) { node = qu.front(); qu.pop(); std::cout << node->data << " "; if(node->left) qu.push(node->left); if(node->right) qu.push(node->right); } std::cout << std::endl; }
二叉树的操作
1.二叉树的插入操作将元素插入到二叉树中,首先我我们需要找到二叉树的插入位置,然后在进行插入操作.
TreeNode* insert(TreeNode *root, int data) { if (!root) { root = new TreeNode(); root->data = data; root->left = nullptr; root->right = nullptr; return root; } else if (data < root->data) root->left = insert(root->left); else root->right = insert(root->right); return root; }
其非递归实现为:
void insert(TreeNode *root, const int data) { if(root==nullptr) { root = new TreeNode(); root->data = data; root->left = nullptr; root->right = nullptr; return ; } TreeNode *node = new treeNode(); node->data = data; node->left = nullptr; node->right = nullptr; treeNode *curr = root; treeNode *parent; while(curr) { parent = curr; curr = data > curr->data ? curr->right : curr->left; } if(data > parent->data) parent->right = node; else parent->left = node; }
2.删除二叉树中的元素
//删除数据 bstree::treeNode * bstree::_delete(treeNode * tree, int data) { if(!tree) return tree; if(data > tree->data) tree->right = _delete(tree->right, data); else if(data < tree->data) tree->left = _delete(tree->left, data); else if ( data == tree->data){ if(tree->left && tree->right) { //如果左右儿子都存在 //从右子树上找一个最小的节点填充该节点 auto node = findMin(tree->right); tree->data = node->data; //从右子树上删除最小的节点 tree->right = _delete(tree->right, tree->data); } else { //只存在一个儿子或者没有 auto node = tree; if(tree->right) tree = tree->right; else tree = tree->left; delete node; } } return tree; }
其上述完整代码为:
#ifndef _BS_TREE_H
#define _BS_TREE_H
#include<iostream>
#include<stack>
#include<queue>
using std::ostream ;
class bstree {
private:
//定义二叉树的存储结构
struct treeNode {
treeNode *left;
treeNode *right;
int data;
};
treeNode *root; //定义根节点
public :
bstree() :
root(nullptr) {}
//插入数据
void insert(int data);
//删除数据
void deleteData(int data) {
_delete(root, data);
}
int getHeight() const {
return _getHeight(root);
}
int findMin() {
if(!root) {
std::cerr << "invalid operation: empty tree" << std::endl;
return -1;
}
return findMin(root)->data;
}
int findMax() {
if(!root) {
std::cerr << "invalid operation: empty tree" << std::endl;
return -1;
}
return findMax(root)->data;
}
/*
*二叉树的遍历
**/
void preOrderTraver();
void inOrderTraver();
void postOrderTraver() {
_postOrderTraver(root);
}
void levelOrderTraver();
private:
void _postOrderTraver(const treeNode *tree);
int _getHeight(const treeNode *tree) const;
treeNode * _delete(treeNode *tree, int data);
treeNode * findMin(treeNode *tree);
treeNode * findMax(treeNode *tree);
};
/*
*插入数据函数
**/
void bstree::insert(const int data)
{
if(root==nullptr) {
//root = new treeNode(data);
root = new treeNode();
root->data = data;
root->left = nullptr;
root->right = nullptr;
return ;
}
//treeNode *node = new treeNode(data);
treeNode *node = new treeNode();
node->data = data;
node->left = nullptr;
node->right = nullptr;
treeNode *curr = root;
treeNode *parent;
while(curr) {
parent = curr;
curr = data > curr->data ? curr->right : curr->left;
}
if(data > parent->data)
parent->right = node;
else
parent->left = node;
}
//删除数据 bstree::treeNode * bstree::_delete(treeNode * tree, int data) { if(!tree) return tree; if(data > tree->data) tree->right = _delete(tree->right, data); else if(data < tree->data) tree->left = _delete(tree->left, data); else if ( data == tree->data){ if(tree->left && tree->right) { //如果左右儿子都存在 //从右子树上找一个最小的节点填充该节点 auto node = findMin(tree->right); tree->data = node->data; //从右子树上删除最小的节点 tree->right = _delete(tree->right, tree->data); } else { //只存在一个儿子或者没有 auto node = tree; if(tree->right) tree = tree->right; else tree = tree->left; delete node; } } return tree; }
bstree::treeNode * bstree::findMin(treeNode *tree)
{
if(!tree)
return tree;
auto node = tree;
while (node->left)
node=node->left;
return node;
}
bstree::treeNode * bstree::findMax(treeNode *tree)
{
if(!tree)
return tree;
auto node=tree;
while (node->right)
node=node->right;
return node;
}
//获取二叉树的高度
int bstree::_getHeight(const treeNode * tree) const
{
if(!tree)
return 0;
else
return 1 + std::max(_getHeight(tree->left), _getHeight(tree->right));
}
/*
*二叉树的遍历操作
**/
//先序遍历
void bstree::preOrderTraver()
{
std::stack<treeNode*> st;
treeNode * node = root;
while(node || !st.empty()) {
while(node) {
std::cout << node->data << " ";
st.push(node);
node = node->left;
}
if(!st.empty()) {
node = st.top();
st.pop();
node = node->right;
}
}
std::cout << std::endl;
}
//中序遍历
void bstree::inOrderTraver()
{
std::stack<treeNode *> st;
auto node = root;
while(node || !st.empty()) {
while(node) {
st.push(node);
node=node->left;
}
if(!st.empty()) {
node =st.top();
st.pop();
std::cout << node->data << " ";
node = node->right;
}
}
std::cout << std::endl;
}
//后序遍历
void bstree::_postOrderTraver(const treeNode *tree)
{
if(tree) {
_postOrderTraver(tree->left);
_postOrderTraver(tree->right);
std::cout << tree->data << " ";
}
}
//层次遍历
void bstree::levelOrderTraver() {
std::queue<treeNode*> qu;
auto node = root;
if(!root)
return ;
qu.push(root);
while(!qu.empty()) {
node = qu.front();
qu.pop();
std::cout << node->data << " ";
if(node->left) qu.push(node->left);
if(node->right) qu.push(node->right);
}
std::cout << std::endl;
}
#endif // _BS_TREE_H
备注:以上资料整理自:数据结构(陈越、何钦铭)
相关文章推荐
- memmove和memcpy
- Android架构
- 小学奥数 余数相同问题
- leetcode_07_Reverse Integer (easy)
- SPOJ GSS7 Can you answer these queries VII
- hdoj 2389 Rain on your Parade 【HK】
- leetcode之Reverse Interger
- thinkphp分页实现
- 浅析Java入门教程之字符常量
- Ubuntu系统下安装curl
- 选择排序—堆排序(Heap Sort)
- 16.Merge Two Sorted Lists
- cocos2d-x Vector的使用
- net开源cms系统
- window.onload、DOMContentLoaded和$(document).ready()
- java 中变量存储位置的区别
- CentOS 7 yum安装路径查询方法
- 天声人語 20151017 追加された議事録
- XML解析
- IOS网络笔记--利用ShareSDK做分享页面(新浪分享Demo)图文教程