二叉排序树C++实现
来源:互联网 发布:淘宝找不到已买的宝贝 编辑:程序博客网 时间:2024/04/29 17:28
简介
学习了算法导论12章关于二叉排序树的内容,自己利用C++实现了二叉排序树的封装。由此对二叉树这种数据结构理解更加深刻了,对于递归在树中的应用之广更是有深切体会,例如递归创建,递归前,中,后序遍历,返回树高(个人最喜欢这个树高递归函数,一句话返回树高确实酷),递归删除等……因为很多树本身就是递归定义的。(删除某节点比较难,有3,4种情况要分别考虑,暂时没有实现,后续再补吧)
有什么不足之处希望不吝赐教!
具体实现
头文件二叉排序树类的定义
注释比较清楚,就不再赘述了:
#pragma once#include<iostream>using namespace std;//树节点定义,包含父节点指针(便于回溯前驱与后继)typedef struct Node { int data; struct Node *leftchild; struct Node *rightchild; struct Node *parent;}Node_t;/*二叉排序树类定义*/class BSearchTree{ public: BSearchTree(void); ~BSearchTree(void); inline Node_t* getRoot() const { return this->root;} void createBSTree(int *dataset, int size); //建立二叉排序树 bool insertNode(Node_t **root, int value); //插入新节点,需要传入二级指针(改变根指针的值) void inorderTraverse(Node_t *root) const; //中序遍历 void visitMiddleOrder() const; //对上一函数继续封装 Node_t* searchNode(Node_t *root,int value) const; //按值查找 void searchByValue(int value) const; //对上一函数继续封装 //最大与最小代码对称 void getMax(Node_t *root) const; //获取最大值 void getMin(Node_t *root) const; //获取最小值 //前驱与后继代码对称 void getPredecessor(Node_t *node); //获取节点前驱 void getSuccessor(Node_t *node); //获取节点后继 int getHeight(Node_t *root) const; //返回树高 private: Node_t *root; //根节点};
成员函数的实现:
#include "BSearchTree.h"BSearchTree::BSearchTree(void){ root = NULL;}BSearchTree::~BSearchTree(void){ //to do sth}//建立二叉排序树(导入数组内元素,逐一插入)void BSearchTree:: createBSTree(int *dataset, int size) { for ( int i=0; i<size; i++ ) { insertNode(&root,dataset[i]); }}//插入新节点//注意因为要修改root根指针的值,所以需要传入二级指针bool BSearchTree:: insertNode(Node_t **root, int value) { //初始化将插入的新节点 Node_t *new_node = new Node_t; if ( new_node == NULL ) { return false; } new_node->data = value; new_node->leftchild = new_node->rightchild = new_node->parent = NULL; //空树时,直接让根指针指向新节点 if( (*root) == NULL ) { *root = new_node; return true; } //插入到当前结点(*root)的左孩子 if ((*root)->leftchild == NULL && (*root)->data > value ) { new_node->parent = (*root); (*root)->leftchild = new_node; return true; } //插入到当前结点(*root)的右孩子 if((*root)->rightchild == NULL && (*root)->data < value){ new_node->parent = (*root); (*root)->rightchild = new_node; return true; } //递归法插入新节点 if ( (*root)->data > value ) { //新节点的值小于根节点,递归寻找左边空位 insertNode( &(*root)->leftchild,value); //关键点 } else if ( (*root)->data < value ) { //新节点的值大于根节点,递归寻找右边空位 insertNode( &(*root)->rightchild,value); } else { return true; }}//中序遍历void BSearchTree:: inorderTraverse(Node_t *root) const { //递归出口 if ( root == NULL ) { return; } inorderTraverse( root->leftchild ); cout<< root->data <<" "; inorderTraverse( root->rightchild );}void BSearchTree::visitMiddleOrder() const { inorderTraverse(this->root);}//按值查找,返回节点的地址Node_t* BSearchTree:: searchNode(Node_t *root,int value) const { if ( root == NULL ) { return NULL; } if ( root->data > value ) { searchNode( root->leftchild,value); } else if ( root->data < value ) { searchNode( root->rightchild,value); } else { return root; }}void BSearchTree:: searchByValue(int value) const{ Node_t *p_findnode = this->searchNode(root,value); if ( p_findnode == NULL ) { cout<<"没有找到该节点"<<endl; } else { cout<< "该节点存在" <<endl; }}//获取最大值void BSearchTree:: getMax(Node_t *root) const { while( root->rightchild ) { root = root->rightchild; } cout<<root->data<<endl;}//获取最小值void BSearchTree:: getMin(Node_t *root) const { while( root->leftchild ) { root = root->leftchild; } cout<<root->data<<endl;}//获取节点前驱void BSearchTree:: getPredecessor(Node_t *node) { //节点如果有左子树,则其前驱节点是左子树的最大值 if ( node->leftchild != NULL ) { return getMax( node->leftchild ); } else { cout<<"(该点无左子树,开始回溯祖先...)"<<endl; } //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继 Node_t *y = node->parent; //y首先指向该节点的父节点 while( y != NULL && node == y->leftchild ) { node = y; y = y->parent; } cout<<y->data;}//获取节点后继void BSearchTree:: getSuccessor(Node_t *node) { //节点如果有右子树,则其后继节点是右子树的最小值 if ( node->rightchild != NULL ) { return getMin( node->rightchild ); } else { cout<<"(该点无右子树,开始回溯祖先...)"<<endl; } //如果没有右子树,则向上回溯,最顶层的祖先节点则是后继 Node_t *y = node->parent; while( y != NULL && node == y->rightchild ) { //遇到第一个“拐角”回溯结束 node = y; //节点向上爬一层 y = y->parent; //y也向上逐层回溯祖先 } cout<<y->data;}//返回树高,树通用写法//ps:算法导论认为只有一个根节点时树高为0,我们常认为1int BSearchTree::getHeight(Node_t *root) const { return root ? max(getHeight(root->leftchild),getHeight(root->rightchild))+1 : -1;}
测试代码:
#include"BSearchTree.h"void main(void) { int arrs[] = { 14,2,4,10,3,5,8,23,18,35 }; //int arrs[] = { 23, 65, 12, 3, 8, 76, 90, 21, 75, 34,345, 61 }; int len = sizeof(arrs) / sizeof(arrs[0]); BSearchTree bsearch_tree; bsearch_tree.createBSTree(arrs,len); cout<<"中序遍历结果: "; bsearch_tree.visitMiddleOrder(); cout<<endl; cout<<"寻找节点3..."<<endl; bsearch_tree.searchByValue(3); cout<<endl; cout<<"寻找节点100..."<<endl; bsearch_tree.searchByValue(100); cout<<endl; cout<<"max :"; bsearch_tree.getMax(bsearch_tree.getRoot()); cout<<"min :"; bsearch_tree.getMin(bsearch_tree.getRoot()); cout<<endl; cout<<"树高:"<< bsearch_tree.getHeight(bsearch_tree.getRoot())<<endl<<endl; Node_t *pnext = bsearch_tree.searchNode(bsearch_tree.getRoot(),4); cout<<"节点"<<pnext->data<<"的后继为:"; bsearch_tree.getSuccessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),4)); pnext = bsearch_tree.searchNode(bsearch_tree.getRoot(),8); cout<<"节点"<<pnext->data<<"的后继为:"; bsearch_tree.getSuccessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),8)); cout<<endl; cout<<endl; Node_t *pbefore = bsearch_tree.searchNode(bsearch_tree.getRoot(),14); cout<<"节点"<<pbefore->data<<"的前驱为:"; bsearch_tree.getPredecessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),14)); pbefore = bsearch_tree.searchNode(bsearch_tree.getRoot(),18); cout<<"节点"<<pbefore->data<<"的前驱为:"; bsearch_tree.getPredecessor(bsearch_tree.searchNode(bsearch_tree.getRoot(),18)); cout<<endl; system("pause");}
运行结果:
0 0
- 二叉排序树 C语言实现
- C实现二叉排序树
- 二叉排序树C实现
- C语言实现二叉排序树
- 二叉排序树实现(C++)
- 二叉排序树的实现(C#)
- 创建二叉排序树C语言实现
- 二叉排序树C语言实现一
- 二叉排序树C语言实现二
- c语言:二叉排序树的实现
- C语言二叉排序树的实现
- 二叉排序树 遍历 ACM 试题 C语言实现
- 二叉排序树C实现(含完整源码)
- 二叉排序树C实现(含完整源码)
- C语言二叉排序树单词计数程序实现
- 二叉排序树C实现(含完整源码)
- 二叉排序树(C与Python分别实现)
- C语言实现二叉排序树的相关操作
- 如何有效的玩转微信
- poj 3295 Tautology
- HDU 1087 Super Jumping! Jumping! Jumping! 最大连续子序列和
- Populating Next Right Pointers in Each Node
- 第二天-模板简单修改(基于t3-bs3-blank模板)
- 二叉排序树C++实现
- 阿里RocketMQ(其前身为metaq)
- 55.iOS6,7坐标起点不一样的原因 图片拉伸 initialize
- 阿里面试总结
- 杭电 4006 The kth great number 队列 附题目翻译
- UVa514 铁轨
- 【汇总】UNP第一个程序daytime端口开启。。。。
- linux文本文件查看、显示命令 :cat head tail grep more less nl
- 7-28