数据结构与算法分析学习笔记--第四章(搜索二叉树,递归和非递归实现删除、插入)

来源:互联网 发布:桌宠软件 编辑:程序博客网 时间:2024/05/19 17:59

基本概念:搜索二叉树,也可称为查找二叉树指的是每个结点的左孩子树上的所有节点值小于该节点的值,右孩子树上所有节点的值大于该节点的值。如:

                                6                                                                                                  6

                              /     \                                                                                          /           \   

                            2        8                                                                                   2                 8    

                          /    \                                                                                        /       \

                       1        4                                                                                 1            4

                               /                                                                                                 /      \

                             3                                                                                               3          7

                      是查找二叉树                                    不是查找二叉树,7节点大于6。而7节点是6的左孩子树中的节点

二叉查找树的平均深度为O(logN)。

查找二叉树类:

/*******************************   serchTree.h*   查找二叉树类*/#include <assert.h>#include <iostream>#include <stack>#define ASSERT assertusing namespace std;//**********************************************************************//结点声明template <typename T>class CBTNode{public:T m_data;//父节点主要用在,获得兄弟结点,获得父节点等函数中,有这个变量的话就不需要遍历整个树了。//如果在资源不是很紧张的情况下,而且对得到父节点或者兄弟结点的功能CBTNode<T> *m_Parent;CBTNode<T> *m_LChild;CBTNode<T> *m_RChild;//拷贝构造函数,浅拷贝。参数赋初值,可以省略CBTNode()这个构造函数CBTNode(T data = T(), CBTNode<T> *Parent = NULL, CBTNode<T> *LChild = NULL, CBTNode<T> *RChild = NULL) : m_data(data), m_Parent(Parent), m_LChild(LChild), m_RChild(RChild){}};//**********************************************************************//树声明template <typename T>class SearchTree {public://*****************************************************************//非递归实现CBTNode<T>* Find(const T &data,CBTNode<T> * node) const;CBTNode<T>* FindMin(CBTNode<T> * node) const;CBTNode<T>* FindMax(CBTNode<T> * node) const;CBTNode<T>* Insert(const T &data, CBTNode<T> * node);CBTNode<T>* Delete(const T &data, CBTNode<T> * node);//*****************************************************************//递归实现CBTNode<T>* DFind(const T &data,CBTNode<T> * node) const;CBTNode<T>* DFindMin(CBTNode<T> * node) const;CBTNode<T>* DFindMax(CBTNode<T> * node) const;CBTNode<T>* DInsert(const T &data, CBTNode<T> * node);CBTNode<T>* DDelete(const T &data, CBTNode<T> * node);public:CBTNode<T> *m_pNodeRoot;};//*************************************************************//非递归实现查找最大结点template <typename T>CBTNode<T> *SearchTree<T>::FindMax(CBTNode<T> * node) const{CBTNode<T> *pMax = node;while(pMax->m_RChild != NULL)pMax = pMax->m_RChild;return pMax;}//*************************************************************//非递归实现查找最小结点template <typename T>CBTNode<T> *SearchTree<T>::FindMin(CBTNode<T> * node) const{CBTNode<T> *pMin = node;while(pMin->m_LChild != NULL)pMin = pMin->m_LChild;return pMin;}//*************************************************************//非递归实现查找template <typename T>CBTNode<T> *SearchTree<T>::Find(const T &data,CBTNode<T> * node) const{CBTNode<T> *pTarget = node;while(pTarget){if(pTarget->m_data < data)pTarget = pTarget->m_LChild;else if(pTarget->m_data > data)pTarget = pTarget->m_RChild;else return pTarget;}return NULL;}//*************************************************************//非递归实现插入template <typename T>CBTNode<T> *SearchTree<T>::Insert(const T &data,CBTNode<T> * node){CBTNode<T> *pTarget = node;CBTNode<T> *pTemp = pTarget;bool isLeft = false;bool isRight = false;while(pTarget){isLeft = isRight = false;pTemp = pTarget;if(pTarget->m_data > data){isLeft = true;pTarget = pTarget->m_LChild;}else if(pTarget->m_data < data){isRight = true;pTarget = pTarget->m_RChild;}else//如果相等 什么都不做break;if(pTarget==NULL){pTarget = new CBTNode<T>(data);pTarget->m_Parent = pTemp;if(isRight)pTemp->m_RChild = pTarget;else if(isLeft)pTemp->m_LChild = pTarget;break;}}return node;}//*************************************************************//非递归实现删除template <typename T>CBTNode<T> *SearchTree<T>::Delete(const T &data,CBTNode<T> * node){CBTNode<T> *pTarget = node;CBTNode<T> *pTempNode;while(pTarget){if(pTarget->m_data > data)pTarget = pTarget->m_LChild;else if(pTarget->m_data < data)pTarget = pTarget->m_RChild;else {pTempNode = pTarget;//如果存在左孩子,则找到左孩子树的最大值,替换当前节点的值,然后删除左孩子树if(pTarget->m_LChild){pTempNode = FindMax(pTarget->m_LChild);}else if(pTarget->m_RChild){pTempNode = FindMin(pTarget->m_RChild);}//如果没有左孩子 也没有右孩子,则直接删除该节点pTarget->m_data = pTempNode->m_data; //如果为父节点的左孩子if(pTempNode->m_Parent->m_LChild && pTempNode->m_data == pTempNode->m_Parent->m_LChild->m_data){pTempNode->m_Parent->m_LChild = NULL;//避免野指针}//如果为父节点的右孩子else{pTempNode->m_Parent->m_RChild = NULL;}delete pTempNode;pTempNode = NULL;break;}}return node;}//*************************************************************//递归实现查找最大结点template <typename T>CBTNode<T> *SearchTree<T>::DFindMax(CBTNode<T> * node) const{if(node == NULL)return NULL;else if(NULL == node->m_RChild)return node;elsereturn DFindMax(node->m_RChild);}//*************************************************************//递归实现查找最小结点template <typename T>CBTNode<T> *SearchTree<T>::DFindMin(CBTNode<T> * node) const{if(node == NULL)return NULL;else if(NULL == node->m_LChild)return node;elsereturn DFindMin(node->m_LChild);}//*************************************************************//递归实现查找template <typename T>CBTNode<T> *SearchTree<T>::DFind(const T &data,CBTNode<T> * node) const{if(node == NULL)return NULL;if(data < node->m_data)return DFind(data, node->m_LChild);else if(data > node->m_data)return DFind(data, node->m_RChild);elsereturn node;}//*************************************************************//递归实现插入template <typename T>CBTNode<T> *SearchTree<T>::DInsert(const T &data,CBTNode<T> * node){if(node == NULL){node = new CBTNode<T>;if(node == NULL)return NULL;node->m_data = data;return node;}else if(data < node->m_data){node->m_LChild = DInsert(data, node->m_LChild);if(node->m_LChild)node->m_LChild->m_Parent = node;}else if(data > node->m_data){node->m_RChild = DInsert(data, node->m_RChild);if(node->m_RChild)node->m_RChild->m_Parent = node;}//当树中已经存在该值的结点时,什么都不做return node;}//*************************************************************//非递归实现删除template <typename T>CBTNode<T> *SearchTree<T>::DDelete(const T &data,CBTNode<T> * node){if(node == NULL){//not found;}else if(data < node->m_data){node->m_LChild = DDelete(data,node->m_LChild);}else if(data > node->m_data){node->m_RChild = DDelete(data,node->m_RChild);}else{if(node->m_LChild && node->m_RChild){CBTNode<T> *pTempNode = DFindMin(node->m_RChild);node->m_data = pTempNode->m_data;node->m_RChild = DDelete(node->m_data,node->m_RChild);}else{//因为这种删除是直接将该节点删除,所以不会有野指针出现。CBTNode<T> *pTempNode = node;if(node->m_LChild ==NULL)node = node->m_RChild;else if(node->m_RChild == NULL)node = node->m_LChild;if (node)node->m_Parent = pTempNode->m_Parent;delete pTempNode;}}return node;}

测试主函数:

#include "SearchTree.h"#include <string>#include <iostream>using namespace std;int _tmain(int argc, _TCHAR* argv[]){CBTNode<int> *root = new CBTNode<int>(6); SearchTree<int> tree1,tree2;tree1.m_pNodeRoot = root;CBTNode<int> *temp = NULL;tree1.Insert(2,tree1.m_pNodeRoot);tree1.Insert(1,tree1.m_pNodeRoot);tree1.Insert(8,tree1.m_pNodeRoot);tree1.Insert(4,tree1.m_pNodeRoot);tree1.Insert(3,tree1.m_pNodeRoot);tree1.Insert(5,tree1.m_pNodeRoot);temp = tree1.FindMax(tree1.m_pNodeRoot);temp = tree1.FindMin(tree1.m_pNodeRoot);tree1.Delete(4,tree1.m_pNodeRoot);tree1.Delete(5,tree1.m_pNodeRoot);tree1.Delete(5,tree1.m_pNodeRoot);CBTNode<int> *root1 = new CBTNode<int>(6); tree2.m_pNodeRoot = root1;tree2.DInsert(2,tree2.m_pNodeRoot);tree2.DInsert(1,tree2.m_pNodeRoot);tree2.DInsert(8,tree2.m_pNodeRoot);tree2.DInsert(4,tree2.m_pNodeRoot);tree2.DInsert(3,tree2.m_pNodeRoot);tree2.DInsert(5,tree2.m_pNodeRoot);temp = tree2.DFindMax(tree2.m_pNodeRoot);temp = tree2.DFindMin(tree2.m_pNodeRoot);tree2.DDelete(4,tree2.m_pNodeRoot);tree2.DDelete(5,tree2.m_pNodeRoot);tree2.DDelete(5,tree2.m_pNodeRoot);return 0;}


0 0