数据结构与算法06:二叉查找树
来源:互联网 发布:淘宝军刀 编辑:程序博客网 时间:2024/05/16 17:08
一、二叉查找树
1、定义一棵二叉查找树
二叉查找树是一棵二叉树:
i)它的根节点大于左孩子节点,但小于右孩子节点
ii)左子树和右子树也是一棵二叉查找树。
2、二叉查找树的插入、查找、删除操作。
二叉查找树最核心的三个操作,下面以删除为例进行解释。
从二叉查找树中删除一个结点:
如果节点是NULL,则返回错误信息;
如果是叶节点,则直接删除就可以;如果不是叶节点,则需要进行拼接操作。
情况1:被删节点左右子树均为空,即删除的是叶子节点,如45.
情况2:被删节点左子树为空,右子树不为空,如30.
情况3:被删节点右子树为空,左子树不为空,如80.
情况4:被删节点左右子树均不为空,如50.
对于情况1:只需把该节点设置为NULL,再释放内存即可
对于情况2:右孩子晋升至该节点的位置,释放内存
对于情况3:左孩子晋升至该节点的位置,释放内存
对于情况4:
把它简化为情况2或情况3。选择简化为情况3,即左子树不为空,右子树为空。
首先,在被删节点50的左子树中,一直往右走,找到最右的元素48 ,交换节点50与节点48。
注意的这里的交换实际只需要把48赋值到被删节点就可以,因为最右的节点最后是删除了的,是不是50不重要。
这时,删除节点50的情况就变成了真正的情况3,即节点50只剩下一个左孩子45了。
template <class elemType>void bSearchTreeType<elemType>::deleteFromTree(nodeType<elemType>* &p){ nodeType<elemType> *current; nodeType<elemType> *trailCurrent; nodeType<elemType> *temp; if (p == NULL) cout << "Error: The node to be deleted is NULL."<< endl; else if (p->lLink == NULL && p->rLink == NULL) //case 1:叶子节点,将p置NULL,释放p的内存 { temp = p; p = NULL; delete temp; }//case 2:没有左子树,将p设置为它的右子节点,释放p的内存 { temp = p; p = temp->rLink; delete temp; } else if (p->rLink == NULL) //case 3:没有右子树,将p设置为它的左子节点,释放p的内存 { temp = p; p = temp->lLink; delete temp; } //case 4:既有左子树,又有右子树,按照假设没有右子树来处理 { current = p->lLink; //游标初始化为左子树的根节点 trailCurrent = NULL; //游标的父节点目前为NULL //游标在左子树中一直向右走 while (current->rLink != NULL) { trailCurrent = current; current = current->rLink; } //最右元素的值赋值给被删元素 p->info = current->info; //如果左子树中没有右子树,此时游标没有动 if (trailCurrent == NULL) p->lLink = current->lLink; else //左子树中有右子树,此时current是最右的那个节点 //把current的左子树拼接到它的父节点的右子树 trailCurrent->rLink = current->lLink; delete current; }}
二、二叉查找树的实现
让二叉查找树继承二叉树抽象类,实现查找、插入和删除方法。
#include "stdafx.h"#include "binaryTree.h"#include <iostream>using namespace std;#pragma region 二叉查找树定义template <class elemType>class bSearchTreeType: public binaryTreeType<elemType>{public: bool search(const elemType& searchItem) const; void insert(const elemType& insertItem); void deleteNode(const elemType& deleteItem);private: void deleteFromTree(nodeType<elemType>* &p); };#pragma endregion 二叉查找树定义template <class elemType>bool bSearchTreeType<elemType>::search(const elemType& searchItem) const{ nodeType<elemType> *current; bool found = false; if (root == NULL) cout << "Cannot search an empty tree." << endl; else { current = root; while (current != NULL && !found) { if (current->info == searchItem) found = true; else if (current->info > searchItem) current = current->lLink; else current = current->rLink; } } return found;}template <class elemType>void bSearchTreeType<elemType>::insert(const elemType& insertItem){ nodeType<elemType> *current; //遍历树的游标 nodeType<elemType> *trailCurrent; //游标的父节点 nodeType<elemType> *newNode; //需要插入的节点 newNode = new nodeType<elemType>; newNode->info = insertItem; newNode->lLink = NULL; newNode->rLink = NULL; if (root == NULL)//空树 root = newNode; else { current = root; while (current != NULL) { trailCurrent = current; if (current->info == insertItem) { cout << "已经存在键为insertItem的节点,不能插入" << endl; return; } else if (current->info > insertItem) current = current->lLink; else current = current->rLink; } if (trailCurrent->info > insertItem) trailCurrent->lLink = newNode; else trailCurrent->rLink = newNode; }}template <class elemType>deleteNode(const elemType& deleteItem){ nodeType<elemType> *current; //遍历树的游标 nodeType<elemType> *trailCurrent; //游标的父节点 bool found = false; if (root == NULL) cout << "Cannot delete from an empty tree." << endl; else { current = root; trailCurrent = root; while (current != NULL && !found) { if (current->info == deleteItem) found = true; else { trailCurrent = current; if (current->info > deleteItem) current = current->lLink; else current = current->rLink; } } if (current == NULL) cout << "The item to be deleted is not in the tree." << endl; else if (found) { if (current == root) deleteFromTree(root); else if (trailCurrent->info > deleteItem) deleteFromTree(trailCurrent->lLink); else deleteFromTree(trailCurrent->rLink); } else cout << "The item to be deleted is not in the tree." << endl; }} template <class elemType>void bSearchTreeType<elemType>::deleteFromTree(nodeType<elemType>* &p){ nodeType<elemType> *current; nodeType<elemType> *trailCurrent; nodeType<elemType> *temp; if (p == NULL) cout << "Error: The node to be deleted is NULL." << endl; else if (p->lLink == NULL && p->rLink == NULL) //case 1:叶子节点,将p置NULL,释放p的内存 { temp = p; p = NULL; delete temp; } else if (p->lLink == NULL) //case 2:没有左子树,将p设置为它的右子节点,释放p的内存 { temp = p; p = temp->rLink; delete temp; } else if (p->rLink == NULL) //case 3:没有右子树,将p设置为它的左子节点,释放p的内存 { temp = p; p = temp->lLink; delete temp; } //case 4:既有左子树,又有右子树,按照假设没有右子树来处理 { current = p->lLink; //当前节点,初始化为左子树的根节点 trailCurrent = NULL; //当前节点的父节点 //将当前节点指向左子树中最右的节点,它为左子树中的最大结点 while (current->rLink != NULL) { trailCurrent = current; current = current->rLink; } //调整p的数据域 p->info = current->info; //调整p的指针领域 if (trailCurrent == NULL) //左子树中没有右子树,此时current没有移动 p->lLink = current->lLink; else//左子树中有右子树,此时current是最右的那个节点 //把current的左子树拼接到它的父节点的右子树 trailCurrent->rLink = current->lLink; delete current; }}
0 0
- 数据结构与算法06:二叉查找树
- 数据结构与算法(二叉查找树)
- 《数据结构与算法分析》--二叉查找树
- <数据结构与算法>之二叉查找树
- 数据结构与算法_二叉查找树
- 数据结构与算法分析-树、二叉树、二叉查找树
- 数据结构与算法JavaScript - 二叉树和二叉查找树
- 【数据结构与算法分析】二叉查找树与AVL树
- 数据结构查找算法之二叉查找树
- 数据结构与算法分析-二叉查找树的实现
- 【数据结构与算法基础】二叉查找树 / Binary Search Tree
- 【算法与数据结构】查找二叉树的实现
- 数据结构与算法简记:二叉查找树相关操作
- [数据结构与算法]二叉树查找结点和最大最小值
- 数据结构与算法(C语言版)__二叉查找树
- 【数据结构与算法】关于二叉查找树的思考
- 数据结构与算法-二叉查找树(java描述)
- 数据结构与算法分析 c++11 查找二叉树 BinarySearchTree
- java.util包---HashSet
- 买了些书,做个计划
- 2016-04-24 html学习 CSS学习
- Nginx+Tomcat动静分离及Nginx优化
- 浮点数保留两位小数
- 数据结构与算法06:二叉查找树
- Scrapy爬取图片
- JSONKit在项目中使用设置(ARC与方法更新)
- 逆元
- acm_非常可乐
- DayDayUp_bug解决_vmware安装无法打开内核设备 \\.\Global\vmx86: 系统找不到指定的文件
- HTML中的表单
- shell学习
- Sitemesh 3 的使用及配置