也是以前写的程序,是实现平衡树的,现在都有点看不懂了,拿出来晒晒.
AVL算法参考: http://www.nocow.cn/index.php/AVL%E6%A0%91
-----------------------------------------------------------------------------------------
describe.h是用来描述返回值的(当初居然用const int,而没有用enum,汗~!)
#ifndef DESCRIBE_H
#define DESCRIBE_H
const int NODE_INSERT_SUCCESS = 0;
const int NODE_NULL_ERROR = 1;
const int NODE_EXIST_ERROR =2;
const int NODE_NOTEXIST_ERROR = 3;
const int NODE_DELETE_SUCCESS = 4;
#endif // DESCRIBE_H
下面就是avltree.h的实现了,由于是用template实现,并且gcc好像不支持template实现放在.cpp文件,因此就写
在一个头文件里面了. (当时是在Linux用gcc调试的,那叫一个累啊,现在都快忘了,皑皑).
#ifndef AVLTREE_H
#define AVLTREE_H
//-INCLUDES---------------------------------------------------------------------------------
#include "describe.h"
#include<iostream>
using namespace std;
//
// The definiation of tree node.
//
template<class T>
class TreeNode
{
public:
// Default Constructor
TreeNode()
{
m_pLeft = NULL;
m_pRight = NULL;
}
// Constructor, parameter data is assigned to m_data
TreeNode(const T& data)
{
m_data = data;
m_pLeft = NULL;
m_pRight = NULL;
}
// Copy Constructor
TreeNode(const TreeNode& node)
{
m_data = node.data;
m_pLeft = NULL;
m_pRight = NULL;
}
// Destructor
~TreeNode()
{
}
// Get the data of current node.
T GetData()
{
return m_data;
}
// Print the data of current node.
void Print()
{
cout << m_data << " ";
}
public:
T m_data;
// Left child node of current node.
TreeNode<T>* m_pLeft;
// Right child node of current node.
TreeNode<T>* m_pRight;
};
//
// The definiation of AVL tree.
//
template<class T>
class AVLTree
{
public:
// Default Constructor
AVLTree();
// Copy Constructor
AVLTree(const AVLTree<T>& tree);
// Operator Assigment
AVLTree& operator=(const AVLTree<T>& tree);
// Destructor
~AVLTree();
// Erase all data in AVLTree
void Erase();
// Get Root node of tree
TreeNode<T> *GetRoot();
// Get Heigh:t of AVLTree
int GetHeight(TreeNode<T> *pNode);
// Insert Node into AVLTree
int InsertNode(const T& data);
// Delete Node from AVLTree
int DeleteNode(const T& data);
// Search Node from AVLTree
bool Search(const T& data);
// Estamite AVLTree is balance
bool IsBalance(TreeNode<T> *pNode);
// Get height between left tree and right tree
int GetLRHeight(TreeNode<T> *pNode);
// Previous order to visit AVLTree
void PreOrder(TreeNode<T> *pNode);
// Post order to visit AVLTree
void PostOrder(TreeNode<T> *pNode);
// Post sort of AVL Tree
void PostSort(TreeNode<T> *pNode);
// Inorder to visit AVLTree
void InOrder(TreeNode<T> *pNode);
// Visit AVLNode
void Visit(TreeNode<T> *pNode);
// Print AVLTree
void Print();
// Left Rotate
TreeNode<T>* LeftRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);
// Right Rotate
TreeNode<T>* RightRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);
// Get Parent Node
TreeNode<T>* GetParent(TreeNode<T> *pNode);
private:
// The balance gene of AVL Tree.
int m_nBalance;
// The root node of AVL Tree.
TreeNode<T> *m_pRoot;
};
/**
* Description: Constructor
* Parameter: None;
* Return: None
*/
template<class T>
AVLTree<T>::AVLTree()
{
m_pRoot = NULL;
m_nBalance == 0;
}
/**
* Description: Copy Constructor
* Parameter: const AVLTree& tree
* Return: None.
*/
template<class T>
AVLTree<T>::AVLTree(const AVLTree<T>& tree)
{
InOrder(tree.m_pRoot);
}
/**
* Description: Assigment Operator
* Parameter: const AVLTree& tree
* Return: None.
*/
template<class T>
AVLTree<T>& AVLTree<T>::operator=(const AVLTree<T>& tree)
{
Erase();
InOrder(tree.m_pRoot);
return *this;
}
/**
* Description: Destructor
* Parameter: NULL
* return: NULL
*/
template<class T>
AVLTree<T>::~AVLTree()
{
Erase();
}
/**
*
*
*
*/
template<class T>
void AVLTree<T>::Erase()
{
PostOrder(m_pRoot);
}
/**
* Description: Get Height of AVLTree
* Parameter: NULL
* Return: Height of AVLTree
*/
template<class T>
int AVLTree<T>::GetHeight(TreeNode<T>* pNode)
{
// If visit at bottom of tree
if (NULL == pNode)
{
return 0;
}
int nLeftHeight = GetHeight(pNode -> m_pLeft);
int nRightHeight = GetHeight(pNode -> m_pRight);
if (nLeftHeight > nRightHeight)
{
return ++nLeftHeight;
}
else
{
return ++nRightHeight;
}
}
/**
* Description: Get root node of AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::GetRoot()
{
return m_pRoot;
}
/**
* Description: Insert tree node into AVLTree, and keep searching
* and balance
* Parameter: A tree node pointer
* Return: Operation result
*/
template<class T>
int AVLTree<T>::InsertNode(const T& data)
{
TreeNode<T>* pNode = NULL;
pNode = new TreeNode<T>(data);
// If m_pRoot is null, assign pNode to m_pRoot
if (NULL == m_pRoot)
{
m_pRoot = new TreeNode<T>;
// It will call assignment operation here.
m_pRoot = pNode;
return NODE_INSERT_SUCCESS;
}
TreeNode<T>* pTempNode = m_pRoot;
while (NULL != pTempNode)
{
// pNode is smaller than tree node
if (pTempNode -> m_data > data)
{
// If left child has element, continue view; else add
// element at left child
if (NULL != pTempNode -> m_pLeft)
{
pTempNode = pTempNode -> m_pLeft;
}
else
{
pTempNode -> m_pLeft = pNode;
break;
}
}
// pNode is bigger than tree node
else if (pTempNode -> m_data < data)
{
// If right child has element, continue view; else add
// element at right child
if (NULL != pTempNode -> m_pRight)
{
pTempNode = pTempNode -> m_pRight;
}
else
{
pTempNode -> m_pRight = pNode;
break;
}
}
// pNode equal tree node, can't be inserted into tree
else if (pTempNode -> m_data == data)
{
delete pNode;
pNode = NULL;
return NODE_EXIST_ERROR;
}
}
// If tree is not balance
return NODE_INSERT_SUCCESS;
}
/**
* Description: Delete tree node from AVLTree, and keep searching
* and balance
* Parameter: A tree node pointer
* Return: Operation result
*/
template<class T>
int AVLTree<T>::DeleteNode(const T& data)
{
// AVLTree is empty
cout << "Delete Data is: " << data << endl;
if (NULL == m_pRoot)
{
return NODE_NOTEXIST_ERROR;
}
TreeNode<T>* pCur = m_pRoot;
TreeNode<T>* pParent = NULL;
// Search If delete node existed
while ((NULL != pCur) && (pCur -> m_data != data))
{
pParent = pCur; // Store pCur's father node
if (pCur -> m_data < data)
{
pCur = pCur -> m_pRight;
}
else if ( pCur -> m_data > data)
{
pCur = pCur -> m_pLeft;
}
}
//No found delete data
if (NULL == pCur)
{
cout << "No found delete data" << endl;
return NODE_NOTEXIST_ERROR;
}
//If pCur has left child.
if ((NULL != pCur -> m_pLeft) && (NULL != pCur -> m_pRight))
{
//Move Left tree's biggest child to pCur and delete pCu.
TreeNode<T>* pReplace = pCur -> m_pLeft;
TreeNode<T>* pTempParent = pCur;
// Find biggest element on delete Node's left tree
while (NULL != pReplace -> m_pRight)
{
pTempParent = pReplace;
pReplace = pReplace -> m_pRight;
}
//Move biggest element to delete node
pCur -> m_data = pReplace -> m_data;
cout << "pReplace Value:" << pReplace -> m_data << endl;
pCur = pReplace;
// For testing
pParent = pTempParent;
}
cout << "pCur Value:" << pCur -> m_data << endl;
TreeNode<T>* temp;
if (NULL != pCur ->m_pLeft)
{
temp = pCur->m_pLeft;
}
else
{
temp = pCur->m_pRight;
}
// Delete node is root
if (pCur == m_pRoot)
{
m_pRoot = temp;
}
else
{
if (pCur == pParent -> m_pLeft)
{
pParent -> m_pLeft = temp;
}
else
{
pParent -> m_pRight = temp;
}
}
delete pCur;
return NODE_DELETE_SUCCESS;
}
/**
* Description: Search tree node from AVLTree
* Parameter: A node pointer
* Return: If data is in tree, return true; else return false
*/
template<class T>
bool AVLTree<T>::Search(const T& data)
{
TreeNode<T> *node = m_pRoot;
while (NULL != node)
{
// Found data !
if (node->m_data == data)
{
return true;
}
else if (node->m_data > data)
{
node = node->m_pLeft;
}
else
{
node = node->m_pRight;
}
}
return false;
}
/**
* Description: Check tree is balance or not
* Parameter: A node pointer
* Return: If tree is balance, return true, else return false
*/
template<class T>
bool AVLTree<T>::IsBalance(TreeNode<T>* pNode)
{
if (pNode == NULL)
{
cout << "node is null" << endl;
return false;
}
else
{
int m_nDis = GetLRHeight(pNode);
if ((m_nDis >= -1) && (m_nDis <= 1))
{
return true;
}
else
{
return false;
}
}
}
/**
* Description: Previous order to visit AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::PreOrder(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
Visit(pNode);
PreOrder(pNode -> m_pLeft);
PreOrder(pNode -> m_pRight);
}
/**
* Description: Post order to visit AVLTree, left child -> right child -> root.
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::PostOrder(TreeNode<T> *pNode)
{
if (NULL == pNode)
{
return;
}
PostOrder(pNode->m_pLeft);
PostOrder(pNode->m_pRight);
// Delete the current node.
delete pNode;
pNode = NULL;
}
/**
* Description: In order to visit AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::InOrder(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
InOrder(pNode -> m_pLeft);
InsertNode(pNode -> m_data);
InOrder(pNode -> m_pRight);
}
/**
* Description: call pNode's print function
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::Visit(TreeNode<T>* pNode)
{
if (NULL != pNode)
{
pNode -> Print();
}
}
/**
* Description: Print AVLTree by previous order
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::Print()
{
PreOrder(m_pRoot);
}
/**
* Description: Left rotate of child tree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::LeftRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
// Rotate tree node is empty
if (NULL == pNode)
{
return NULL;
}
// deal with root node
if (pNode == m_pRoot)
{
m_pRoot = pNode -> m_pLeft;
pNode -> m_pLeft = m_pRoot -> m_pRight;
m_pRoot -> m_pRight = pNode;
return m_pRoot;
}
else
{
T data = pNode -> m_data;
TreeNode<T>* pTemp = pNode;
pNode = pNode -> m_pLeft;
pTemp -> m_pLeft = pNode -> m_pRight;
pNode -> m_pRight = pTemp;
if ((pParent -> m_pLeft != NULL) &&
(data == pParent -> m_pLeft -> m_data))
{
pParent -> m_pLeft = pNode;
}
else if ((pParent -> m_pRight != NULL) &&
(data == pParent -> m_pRight -> m_data))
{
pParent -> m_pRight = pNode;
}
return pNode;
}
}
/**
* Description: Right rotate of child tree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::RightRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
if (NULL == pNode)
{
return NULL;
}
// deal with root node
if (pNode == m_pRoot)
{
m_pRoot = pNode -> m_pRight;
pNode -> m_pRight = m_pRoot -> m_pLeft;
m_pRoot -> m_pLeft = pNode;
return m_pRoot;
}
else
{
T data = pNode -> m_data;
TreeNode<T>* pTemp = pNode;
pNode = pNode -> m_pRight;
pTemp -> m_pRight = pNode -> m_pLeft;
pNode -> m_pLeft = pTemp;
if ((NULL != pParent -> m_pLeft) &&
(data == pParent -> m_pLeft -> m_data))
{
pParent -> m_pLeft = pNode;
}
else if ((NULL != pParent -> m_pRight)
&& (data == pParent -> m_pRight -> m_data))
{
pParent -> m_pRight = pNode;
}
return pNode;
}
}
template<class T>
int AVLTree<T>::GetLRHeight(TreeNode<T>* pNode)
{
if(NULL == pNode)
{
return 0;
}
int nLeft = GetHeight(pNode -> m_pLeft);
int nRight = GetHeight(pNode -> m_pRight);
return nLeft - nRight;
}
template<class T>
TreeNode<T>* AVLTree<T>::GetParent(TreeNode<T>* pNode)
{
if ((pNode == NULL) || (m_pRoot == NULL) || (pNode == m_pRoot))
{
return NULL;
}
TreeNode<T>* pTemp = m_pRoot;
T eData = pNode -> m_data;
if (eData != m_pRoot -> m_data)
{
while (!((pTemp -> m_pLeft == NULL) &&
(pTemp -> m_pRight == NULL)))
{
if (pTemp -> m_pLeft != NULL && pTemp -> m_pRight != NULL)
{
if ((pTemp -> m_pLeft -> m_data == eData) ||
(pTemp -> m_pRight -> m_data == eData))
{
return pTemp;
}
else if (pTemp -> m_data > eData)
{
pTemp = pTemp -> m_pLeft;
}
else if (pTemp -> m_data < eData)
{
pTemp = pTemp -> m_pRight;
}
}
else if (pTemp -> m_pLeft != NULL &&
pTemp -> m_pRight == NULL)
{
if (pTemp -> m_pLeft -> m_data == eData)
{
return pTemp;
}
else if (pTemp -> m_data > eData)
{
pTemp = pTemp -> m_pLeft;
}
}
else if (pTemp -> m_pRight != NULL &&
pTemp -> m_pLeft == NULL)
{
if (pTemp -> m_pRight -> m_data == eData)
{
return pTemp;
}
else if (pTemp -> m_data < eData)
{
pTemp = pTemp -> m_pRight;
}
}
}
return NULL;
}
else
{
return NULL;
}
}
template<class T>
void AVLTree<T>::PostSort(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
// Print();
cout << endl;
PostSort(pNode -> m_pLeft);
PostSort(pNode -> m_pRight);
if (IsBalance(pNode) == true)
{
return;
}
else
{
TreeNode<T>* pParent = GetParent(pNode);
while (false == IsBalance(pNode))
{
TreeNode<T>* pRecord = NULL;
if (GetLRHeight(pNode) < -1)
{
if (GetLRHeight(pNode -> m_pRight) == 1)
{
TreeNode<T>* Ptr = LeftRotate(pNode -> m_pRight, pNode);
pNode -> m_pRight = Ptr;
}
pRecord = RightRotate(pNode, pParent);
pNode = pRecord;
}
else if (GetLRHeight(pNode) > 1)
{
// RL style
if (GetLRHeight(pNode -> m_pLeft) == -1)
{
TreeNode<T>* Ptr = RightRotate(pNode -> m_pLeft, pNode);
pNode -> m_pLeft = Ptr;
}
pRecord = LeftRotate(pNode, pParent);
pNode = pRecord;
}
}
}
//Print();
}
#endif
AVL算法参考: http://www.nocow.cn/index.php/AVL%E6%A0%91
-----------------------------------------------------------------------------------------
describe.h是用来描述返回值的(当初居然用const int,而没有用enum,汗~!)
#ifndef DESCRIBE_H
#define DESCRIBE_H
const int NODE_INSERT_SUCCESS = 0;
const int NODE_NULL_ERROR = 1;
const int NODE_EXIST_ERROR =2;
const int NODE_NOTEXIST_ERROR = 3;
const int NODE_DELETE_SUCCESS = 4;
#endif // DESCRIBE_H
下面就是avltree.h的实现了,由于是用template实现,并且gcc好像不支持template实现放在.cpp文件,因此就写
在一个头文件里面了. (当时是在Linux用gcc调试的,那叫一个累啊,现在都快忘了,皑皑).
#ifndef AVLTREE_H
#define AVLTREE_H
//-INCLUDES---------------------------------------------------------------------------------
#include "describe.h"
#include<iostream>
using namespace std;
//
// The definiation of tree node.
//
template<class T>
class TreeNode
{
public:
// Default Constructor
TreeNode()
{
m_pLeft = NULL;
m_pRight = NULL;
}
// Constructor, parameter data is assigned to m_data
TreeNode(const T& data)
{
m_data = data;
m_pLeft = NULL;
m_pRight = NULL;
}
// Copy Constructor
TreeNode(const TreeNode& node)
{
m_data = node.data;
m_pLeft = NULL;
m_pRight = NULL;
}
// Destructor
~TreeNode()
{
}
// Get the data of current node.
T GetData()
{
return m_data;
}
// Print the data of current node.
void Print()
{
cout << m_data << " ";
}
public:
T m_data;
// Left child node of current node.
TreeNode<T>* m_pLeft;
// Right child node of current node.
TreeNode<T>* m_pRight;
};
//
// The definiation of AVL tree.
//
template<class T>
class AVLTree
{
public:
// Default Constructor
AVLTree();
// Copy Constructor
AVLTree(const AVLTree<T>& tree);
// Operator Assigment
AVLTree& operator=(const AVLTree<T>& tree);
// Destructor
~AVLTree();
// Erase all data in AVLTree
void Erase();
// Get Root node of tree
TreeNode<T> *GetRoot();
// Get Heigh:t of AVLTree
int GetHeight(TreeNode<T> *pNode);
// Insert Node into AVLTree
int InsertNode(const T& data);
// Delete Node from AVLTree
int DeleteNode(const T& data);
// Search Node from AVLTree
bool Search(const T& data);
// Estamite AVLTree is balance
bool IsBalance(TreeNode<T> *pNode);
// Get height between left tree and right tree
int GetLRHeight(TreeNode<T> *pNode);
// Previous order to visit AVLTree
void PreOrder(TreeNode<T> *pNode);
// Post order to visit AVLTree
void PostOrder(TreeNode<T> *pNode);
// Post sort of AVL Tree
void PostSort(TreeNode<T> *pNode);
// Inorder to visit AVLTree
void InOrder(TreeNode<T> *pNode);
// Visit AVLNode
void Visit(TreeNode<T> *pNode);
// Print AVLTree
void Print();
// Left Rotate
TreeNode<T>* LeftRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);
// Right Rotate
TreeNode<T>* RightRotate(TreeNode<T> *pNode, TreeNode<T> *pParent);
// Get Parent Node
TreeNode<T>* GetParent(TreeNode<T> *pNode);
private:
// The balance gene of AVL Tree.
int m_nBalance;
// The root node of AVL Tree.
TreeNode<T> *m_pRoot;
};
/**
* Description: Constructor
* Parameter: None;
* Return: None
*/
template<class T>
AVLTree<T>::AVLTree()
{
m_pRoot = NULL;
m_nBalance == 0;
}
/**
* Description: Copy Constructor
* Parameter: const AVLTree& tree
* Return: None.
*/
template<class T>
AVLTree<T>::AVLTree(const AVLTree<T>& tree)
{
InOrder(tree.m_pRoot);
}
/**
* Description: Assigment Operator
* Parameter: const AVLTree& tree
* Return: None.
*/
template<class T>
AVLTree<T>& AVLTree<T>::operator=(const AVLTree<T>& tree)
{
Erase();
InOrder(tree.m_pRoot);
return *this;
}
/**
* Description: Destructor
* Parameter: NULL
* return: NULL
*/
template<class T>
AVLTree<T>::~AVLTree()
{
Erase();
}
/**
*
*
*
*/
template<class T>
void AVLTree<T>::Erase()
{
PostOrder(m_pRoot);
}
/**
* Description: Get Height of AVLTree
* Parameter: NULL
* Return: Height of AVLTree
*/
template<class T>
int AVLTree<T>::GetHeight(TreeNode<T>* pNode)
{
// If visit at bottom of tree
if (NULL == pNode)
{
return 0;
}
int nLeftHeight = GetHeight(pNode -> m_pLeft);
int nRightHeight = GetHeight(pNode -> m_pRight);
if (nLeftHeight > nRightHeight)
{
return ++nLeftHeight;
}
else
{
return ++nRightHeight;
}
}
/**
* Description: Get root node of AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::GetRoot()
{
return m_pRoot;
}
/**
* Description: Insert tree node into AVLTree, and keep searching
* and balance
* Parameter: A tree node pointer
* Return: Operation result
*/
template<class T>
int AVLTree<T>::InsertNode(const T& data)
{
TreeNode<T>* pNode = NULL;
pNode = new TreeNode<T>(data);
// If m_pRoot is null, assign pNode to m_pRoot
if (NULL == m_pRoot)
{
m_pRoot = new TreeNode<T>;
// It will call assignment operation here.
m_pRoot = pNode;
return NODE_INSERT_SUCCESS;
}
TreeNode<T>* pTempNode = m_pRoot;
while (NULL != pTempNode)
{
// pNode is smaller than tree node
if (pTempNode -> m_data > data)
{
// If left child has element, continue view; else add
// element at left child
if (NULL != pTempNode -> m_pLeft)
{
pTempNode = pTempNode -> m_pLeft;
}
else
{
pTempNode -> m_pLeft = pNode;
break;
}
}
// pNode is bigger than tree node
else if (pTempNode -> m_data < data)
{
// If right child has element, continue view; else add
// element at right child
if (NULL != pTempNode -> m_pRight)
{
pTempNode = pTempNode -> m_pRight;
}
else
{
pTempNode -> m_pRight = pNode;
break;
}
}
// pNode equal tree node, can't be inserted into tree
else if (pTempNode -> m_data == data)
{
delete pNode;
pNode = NULL;
return NODE_EXIST_ERROR;
}
}
// If tree is not balance
return NODE_INSERT_SUCCESS;
}
/**
* Description: Delete tree node from AVLTree, and keep searching
* and balance
* Parameter: A tree node pointer
* Return: Operation result
*/
template<class T>
int AVLTree<T>::DeleteNode(const T& data)
{
// AVLTree is empty
cout << "Delete Data is: " << data << endl;
if (NULL == m_pRoot)
{
return NODE_NOTEXIST_ERROR;
}
TreeNode<T>* pCur = m_pRoot;
TreeNode<T>* pParent = NULL;
// Search If delete node existed
while ((NULL != pCur) && (pCur -> m_data != data))
{
pParent = pCur; // Store pCur's father node
if (pCur -> m_data < data)
{
pCur = pCur -> m_pRight;
}
else if ( pCur -> m_data > data)
{
pCur = pCur -> m_pLeft;
}
}
//No found delete data
if (NULL == pCur)
{
cout << "No found delete data" << endl;
return NODE_NOTEXIST_ERROR;
}
//If pCur has left child.
if ((NULL != pCur -> m_pLeft) && (NULL != pCur -> m_pRight))
{
//Move Left tree's biggest child to pCur and delete pCu.
TreeNode<T>* pReplace = pCur -> m_pLeft;
TreeNode<T>* pTempParent = pCur;
// Find biggest element on delete Node's left tree
while (NULL != pReplace -> m_pRight)
{
pTempParent = pReplace;
pReplace = pReplace -> m_pRight;
}
//Move biggest element to delete node
pCur -> m_data = pReplace -> m_data;
cout << "pReplace Value:" << pReplace -> m_data << endl;
pCur = pReplace;
// For testing
pParent = pTempParent;
}
cout << "pCur Value:" << pCur -> m_data << endl;
TreeNode<T>* temp;
if (NULL != pCur ->m_pLeft)
{
temp = pCur->m_pLeft;
}
else
{
temp = pCur->m_pRight;
}
// Delete node is root
if (pCur == m_pRoot)
{
m_pRoot = temp;
}
else
{
if (pCur == pParent -> m_pLeft)
{
pParent -> m_pLeft = temp;
}
else
{
pParent -> m_pRight = temp;
}
}
delete pCur;
return NODE_DELETE_SUCCESS;
}
/**
* Description: Search tree node from AVLTree
* Parameter: A node pointer
* Return: If data is in tree, return true; else return false
*/
template<class T>
bool AVLTree<T>::Search(const T& data)
{
TreeNode<T> *node = m_pRoot;
while (NULL != node)
{
// Found data !
if (node->m_data == data)
{
return true;
}
else if (node->m_data > data)
{
node = node->m_pLeft;
}
else
{
node = node->m_pRight;
}
}
return false;
}
/**
* Description: Check tree is balance or not
* Parameter: A node pointer
* Return: If tree is balance, return true, else return false
*/
template<class T>
bool AVLTree<T>::IsBalance(TreeNode<T>* pNode)
{
if (pNode == NULL)
{
cout << "node is null" << endl;
return false;
}
else
{
int m_nDis = GetLRHeight(pNode);
if ((m_nDis >= -1) && (m_nDis <= 1))
{
return true;
}
else
{
return false;
}
}
}
/**
* Description: Previous order to visit AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::PreOrder(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
Visit(pNode);
PreOrder(pNode -> m_pLeft);
PreOrder(pNode -> m_pRight);
}
/**
* Description: Post order to visit AVLTree, left child -> right child -> root.
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::PostOrder(TreeNode<T> *pNode)
{
if (NULL == pNode)
{
return;
}
PostOrder(pNode->m_pLeft);
PostOrder(pNode->m_pRight);
// Delete the current node.
delete pNode;
pNode = NULL;
}
/**
* Description: In order to visit AVLTree
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::InOrder(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
InOrder(pNode -> m_pLeft);
InsertNode(pNode -> m_data);
InOrder(pNode -> m_pRight);
}
/**
* Description: call pNode's print function
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::Visit(TreeNode<T>* pNode)
{
if (NULL != pNode)
{
pNode -> Print();
}
}
/**
* Description: Print AVLTree by previous order
* Parameter: NULL
* Return: NULL
*/
template<class T>
void AVLTree<T>::Print()
{
PreOrder(m_pRoot);
}
/**
* Description: Left rotate of child tree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::LeftRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
// Rotate tree node is empty
if (NULL == pNode)
{
return NULL;
}
// deal with root node
if (pNode == m_pRoot)
{
m_pRoot = pNode -> m_pLeft;
pNode -> m_pLeft = m_pRoot -> m_pRight;
m_pRoot -> m_pRight = pNode;
return m_pRoot;
}
else
{
T data = pNode -> m_data;
TreeNode<T>* pTemp = pNode;
pNode = pNode -> m_pLeft;
pTemp -> m_pLeft = pNode -> m_pRight;
pNode -> m_pRight = pTemp;
if ((pParent -> m_pLeft != NULL) &&
(data == pParent -> m_pLeft -> m_data))
{
pParent -> m_pLeft = pNode;
}
else if ((pParent -> m_pRight != NULL) &&
(data == pParent -> m_pRight -> m_data))
{
pParent -> m_pRight = pNode;
}
return pNode;
}
}
/**
* Description: Right rotate of child tree
* Parameter: NULL
* Return: NULL
*/
template<class T>
TreeNode<T>* AVLTree<T>::RightRotate(TreeNode<T>* pNode, TreeNode<T>* pParent)
{
if (NULL == pNode)
{
return NULL;
}
// deal with root node
if (pNode == m_pRoot)
{
m_pRoot = pNode -> m_pRight;
pNode -> m_pRight = m_pRoot -> m_pLeft;
m_pRoot -> m_pLeft = pNode;
return m_pRoot;
}
else
{
T data = pNode -> m_data;
TreeNode<T>* pTemp = pNode;
pNode = pNode -> m_pRight;
pTemp -> m_pRight = pNode -> m_pLeft;
pNode -> m_pLeft = pTemp;
if ((NULL != pParent -> m_pLeft) &&
(data == pParent -> m_pLeft -> m_data))
{
pParent -> m_pLeft = pNode;
}
else if ((NULL != pParent -> m_pRight)
&& (data == pParent -> m_pRight -> m_data))
{
pParent -> m_pRight = pNode;
}
return pNode;
}
}
template<class T>
int AVLTree<T>::GetLRHeight(TreeNode<T>* pNode)
{
if(NULL == pNode)
{
return 0;
}
int nLeft = GetHeight(pNode -> m_pLeft);
int nRight = GetHeight(pNode -> m_pRight);
return nLeft - nRight;
}
template<class T>
TreeNode<T>* AVLTree<T>::GetParent(TreeNode<T>* pNode)
{
if ((pNode == NULL) || (m_pRoot == NULL) || (pNode == m_pRoot))
{
return NULL;
}
TreeNode<T>* pTemp = m_pRoot;
T eData = pNode -> m_data;
if (eData != m_pRoot -> m_data)
{
while (!((pTemp -> m_pLeft == NULL) &&
(pTemp -> m_pRight == NULL)))
{
if (pTemp -> m_pLeft != NULL && pTemp -> m_pRight != NULL)
{
if ((pTemp -> m_pLeft -> m_data == eData) ||
(pTemp -> m_pRight -> m_data == eData))
{
return pTemp;
}
else if (pTemp -> m_data > eData)
{
pTemp = pTemp -> m_pLeft;
}
else if (pTemp -> m_data < eData)
{
pTemp = pTemp -> m_pRight;
}
}
else if (pTemp -> m_pLeft != NULL &&
pTemp -> m_pRight == NULL)
{
if (pTemp -> m_pLeft -> m_data == eData)
{
return pTemp;
}
else if (pTemp -> m_data > eData)
{
pTemp = pTemp -> m_pLeft;
}
}
else if (pTemp -> m_pRight != NULL &&
pTemp -> m_pLeft == NULL)
{
if (pTemp -> m_pRight -> m_data == eData)
{
return pTemp;
}
else if (pTemp -> m_data < eData)
{
pTemp = pTemp -> m_pRight;
}
}
}
return NULL;
}
else
{
return NULL;
}
}
template<class T>
void AVLTree<T>::PostSort(TreeNode<T>* pNode)
{
if (NULL == pNode)
{
return;
}
// Print();
cout << endl;
PostSort(pNode -> m_pLeft);
PostSort(pNode -> m_pRight);
if (IsBalance(pNode) == true)
{
return;
}
else
{
TreeNode<T>* pParent = GetParent(pNode);
while (false == IsBalance(pNode))
{
TreeNode<T>* pRecord = NULL;
if (GetLRHeight(pNode) < -1)
{
if (GetLRHeight(pNode -> m_pRight) == 1)
{
TreeNode<T>* Ptr = LeftRotate(pNode -> m_pRight, pNode);
pNode -> m_pRight = Ptr;
}
pRecord = RightRotate(pNode, pParent);
pNode = pRecord;
}
else if (GetLRHeight(pNode) > 1)
{
// RL style
if (GetLRHeight(pNode -> m_pLeft) == -1)
{
TreeNode<T>* Ptr = RightRotate(pNode -> m_pLeft, pNode);
pNode -> m_pLeft = Ptr;
}
pRecord = LeftRotate(pNode, pParent);
pNode = pRecord;
}
}
}
//Print();
}
#endif