算法导论(5) 二叉搜索树
来源:互联网 发布:我是一名淘宝差评师 编辑:程序博客网 时间:2024/06/05 07:02
二叉搜索树
设x是二叉搜索树的一个结点,如果y是x左子树的一个结点,那么y.key≤x.key,如果y是x有字数的一个结点,那么y.key≥x.key。
二叉树有三种遍历的方法:
先序遍历:输出根的关键字在其左右子树的关键字之前。
中序遍历:输出根的关键字在其左右子树的关键字之间。
后序遍历:输出根的关键字在其左右子树的关键字之后。
主要的操作包括查找,遍历,最大最小关键字寻找,前驱后继结点查找,插入和删除。代码如下:
class Node{private: int key;//值public: Node *left;//左子树 Node *right;//右子树 Node *parent;//父结点 int getkey(); void setkey(int k); Node(int k = 0); bool operator == (Node &z); Node& operator = (Node &z);};//二叉搜索树class BSTree{public: Node *root; BSTree(){ root = NULL; } void treeinsert(Node &root, Node &z);//插入结点 Node treesearch(Node *root, int k);//查询结点 void treewalk(Node *root);//遍历 Node treemin(Node *root);//寻找结点root下最小值结点 Node treemax(Node *root);//寻找结点root下最大值结点 Node treesuccessor(Node *x);//寻找结点x的后继结点 Node treeprodecessor(Node *x);//寻找结点x的前驱结点 void treetransplant(Node &root, Node *u, Node *v);//在根结点root下移动子树v到u void treedelete(Node &root, Node *z);//删除结点};#include<iostream>#include"BinarySearchTree.h"using namespace std;Node::Node(int k):key(k){ left = NULL; right = NULL; parent = NULL;}bool Node::operator == (Node &z){ if ((key == z.key)&&(left == z.left)&&(right == z.right)&&(parent == z.parent)) { return true; } else{ return false; }}Node& Node::operator = (Node &z){ delete left; delete right; delete parent; left = z.left; right = z.right; parent = z.parent; key = z.key; z.left = NULL; z.right = NULL; z.parent = NULL; return *this;}int Node::getkey(){ return key;}void Node::setkey(int k){ key = k;}//查询、最大值、最小值、前驱、后继函数均可以在O(h)时间内完成,h为树的高度Node BSTree::treesearch(Node *root, int k)//查询结点{ //递归版本 if (k == root->getkey()) { return *root; } if (k < root->getkey()) { return treesearch(root->left, k); } else { return treesearch(root->right, k); } return 0;}void BSTree::treewalk(Node *root)//中序遍历{ if (root != NULL) { treewalk(root->left); cout << root->getkey() << " "; treewalk(root->right); }}Node BSTree::treemin(Node *root)//寻找结点root下最小值结点{ //最左边最小 Node *x; x = root; while (x->left != NULL) { x = x->left; } return *x;}Node BSTree::treemax(Node *root)//寻找结点root下最大值结点{ //最右边最大 Node *x; x = root; if (x->right != NULL) { return treemax(x->right); } return *x;}Node BSTree::treesuccessor(Node *x)//寻找结点x的后继结点{ Node *y; //如果右孩子不空,则右子树中的最小值即为后继 if (x->right != NULL){ return treemin(x->right); } y = x->parent; //如果父结点也为空,无后继结点 //父结点存在时,后继结点为它的最底层祖先,并且后继结点的左结点也是它的祖先 //因此循环的终止条件为x == y->right,当x是一个左孩子时终止,x的父结点为后继结点 while (y != NULL && x == y->right) { x = y; y = y->parent; } //y=NULL时,返回y会出错 if (y != NULL) { return *y; } return 0;}Node BSTree::treeprodecessor(Node *x)//寻找结点x的前驱结点{ Node *y; //如果左孩子存在,前驱结点为左子树中最大值 if (x->left != NULL){ return treemax(x->left); } y = x->parent; //与后继结点类似,当x为右孩子时终止,x父结点为前驱结点 while (y != NULL && x == y->left) { x = y; y = y->parent; } if (y != NULL) { return *y; } return 0;}void BSTree::treeinsert(Node &root, Node &z)//插入结点{ Node *x, *y = NULL; x = &root; //向下寻找位置 while (x != NULL) { y = x; if (z.getkey() < x->getkey()) { x = x->left; } else{ x = x->right; } } z.parent = y; //判断树是否为空 if (y == NULL) { root = z; } else if (z.getkey() < y->getkey()) { y->left = &z; } else{ y->right = &z; }}void BSTree::treetransplant(Node &root, Node *u, Node *v)//在根结点root下移动子树v到u{ //u为根结点 if (u->parent == NULL) { root = *v; } else if (u == u->parent->left) { u->parent->left = v; } else{ u->parent->right = v; } if (v != NULL) { v->parent = u->parent; }}void BSTree::treedelete(Node &root, Node *z)//删除结点{ Node *y=new Node; if (z->left == NULL){ //如果左孩子为空,利用右孩子替换,右孩子为空时,相当于直接删除 treetransplant(root, z, z->right); } else if (z->right == NULL){ //执行此步时,一定只有左孩子,拿左孩子替换即可 treetransplant(root, z, z->left); } else{ //左右孩子都存在,首先需要寻找它的后继结点 y= &treemin(z->right); if (!(*y == *z->right)){ //如果后继结点不是它的右孩子,后继结点没有左孩子,否则不是后继结点 //先拿后继结点右孩子替换后继结点,再拿后继结点替换要删除的结点 treetransplant(root, y, y->right); //将z的右孩子换到y上,if外的语句把z的左孩子换到y上 y->right = z->right; y->right->parent = y; } //如果后继结点就是它的右孩子,并且这个右孩子没有左孩子,否则不可能是后继结点,因此直接拿后继结点替换 treetransplant(root, z, y); y->left = z->left; y->left->parent = y; } }
结构上,指针、引用的应用都比较乱,只做参考。
0 0
- 算法导论(5) 二叉搜索树
- 二叉搜索树(算法导论)
- 算法导论12(二叉搜索树)
- 算法导论-----二叉搜索树
- 算法导论-----------二叉搜索树
- 算法导论 二叉搜索树
- 算法导论--二叉搜索树
- 【算法导论】二叉搜索树
- 算法导论二叉搜索树
- 算法导论 二叉搜索树
- 算法导论二叉搜索树
- 算法导论 二叉搜索树
- 二叉搜索树的详解(算法导论读书笔记)
- 二叉搜索树(算法导论第12章)
- 动态规划之最优二叉搜索树(算法导论)
- 算法导论-第12章-二叉搜索(查找)树
- 二叉搜索树——《算法导论》学习心得(十二)
- 算法导论读书笔记(12)二叉搜索树
- java中的null和""区别
- hdoj 5499 SDOI 【结构体排序】
- 浏览器兼容
- 几个常用(伪)汇编指令详解
- 不同的域名指向同一个主机上的不同项目
- 算法导论(5) 二叉搜索树
- Ol3中Map事件全解析
- Android中常用的优秀开源框架
- 新的开始
- 英语写作
- pdo 连库
- Android百度地图(四)如何引入离线地图包
- hd1084 What Is Your Grade?
- HDU5724 Chess