二叉树链式存储的常用操作及实现代码
1.节点标记
enum ECCHILDSIGN
{
E_Root,
E_ChildLeft,
E_ChildRight
};
2.树中每个节点的定义
template <typename T>
struct BinaryTreeNode
{
T data;
BinaryTreeNode* leftChild;
BinaryTreeNode* rightChild;
};
3.二叉树的定义
template <typename T>
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
BinaryTreeNode<T>* CreateNode(BinaryTreeNode<T>* parent, ECCHILDSIGN pointsign, const T& e);
void RleaseNode(BinaryTreeNode<T>* pnode);
void CreateBiTreeAccordPT(char* pstr);
void preOrder();
void inOrder();
void postOrder();
void levelOrder();
int getSize();
int getHeight();
BinaryTreeNode<T>* SearchElem(const T& e);
BinaryTreeNode<T>* GetParent(BinaryTreeNode<T>* tSonNode);
void CopyTree(BinaryTree<T>* targettree);
void preOrder_noRecu();
void inOrder_noRecu();
void postOrder_noRecu();
void CreateBTreeAccordPI(char *pP_T,char *pI_T);
void CreateBTreeAccordPO(char* pP_T, char* pI_T);
private:
BinaryTreeNode<T>* root;
void CreateBiTreeAccordPTRecu(BinaryTreeNode<T>*& tnode,char* &pstr);
void preOrder(BinaryTreeNode<T>* tNode);
void inOrder(BinaryTreeNode<T>* tNode);
void postOrder(BinaryTreeNode<T>* tNode);
void levelOrder(BinaryTreeNode<T>* tNode);
int getSize(BinaryTreeNode<T>* tNode);
int getHeight(BinaryTreeNode<T>* tNode);
BinaryTreeNode<T>* SearchElem(BinaryTreeNode<T>* tNode, const T& e);
void CopyTree(BinaryTreeNode<T>* tSouce, BinaryTreeNode<T>*& tTarget);
void preOrder_noRecu(BinaryTreeNode<T>* tNode);
void inOrder_noRecu(BinaryTreeNode<T>* tNode);
void postOrder_noRecu(BinaryTreeNode<T>* tNode);
void CreateBTreeAccordPI(BinaryTreeNode<T>* &tNode, char* pP_T, char* pI_T, int n);
void CreateBTreeAccordPO(BinaryTreeNode<T>*& tNode, char* pP_T, char* pI_T, int n);
};
4.构造函数和析构函数
template<typename T>
BinaryTree<T>::BinaryTree()
{
root = nullptr;
}
template<typename T>
BinaryTree<T>::~BinaryTree()
{
RleaseNode(root);
}
5.释放二叉树节点操作
template <typename T>
void BinaryTree<T>::RleaseNode(BinaryTreeNode<T>* pnode)
{
if (pnode != nullptr)
{
RleaseNode(pnode->leftChild);
RleaseNode(pnode->rightChild);
}
delete pnode;
}
6.创建一个树节点
enum ECCHILDSIGN
{
E_Root,
E_ChildLeft,
E_ChildRight
};
7.利用扩展二叉树的前序遍历序列来创建一棵二叉树
template <typename T>
void BinaryTree<T>::CreateBiTreeAccordPT(char* pstr)
{
CreateBiTreeAccordPTRecu(root, pstr);
}
template <typename T>
void BinaryTree<T>::CreateBiTreeAccordPTRecu(BinaryTreeNode<T>*& tnode, char*& pstr)
{
if (*pstr == '#')
{
tnode = nullptr;
}
else
{
tnode = new BinaryTreeNode<T>;
tnode->data = *pstr;
CreateBiTreeAccordPTRecu(tnode->leftChild, ++pstr);
CreateBiTreeAccordPTRecu(tnode->rightChild, ++pstr);
}
}
8.遍历操作
(1)前序遍历二叉树
template <typename T>
void BinaryTree<T>::preOrder()
{
preOrder(root);
}
template <typename T>
void BinaryTree<T>::preOrder(BinaryTreeNode<T>* tNode)
{
if (tNode != nullptr)
{
cout << tNode->data << " ";
preOrder(tNode->leftChild);
preOrder(tNode->rightChild);
}
}
(2)中序遍历二叉树
template <typename T>
void BinaryTree<T>::inOrder()
{
inOrder(root);
}
template <typename T>
void BinaryTree<T>::inOrder(BinaryTreeNode<T>* tNode)
{
if (tNode != nullptr)
{
inOrder(tNode->leftChild);
cout << tNode->data << " ";
inOrder(tNode->rightChild);
}
}
(3)后序遍历二叉树
template <typename T>
void BinaryTree<T>::postOrder()
{
postOrder(root);
}
template <typename T>
void BinaryTree<T>::postOrder(BinaryTreeNode<T>* tNode)
{
if (tNode != nullptr)
{
postOrder(tNode->leftChild);
postOrder(tNode->rightChild);
cout << tNode->data << " ";
}
}
(4)层序遍历二叉树(使用队列实现)
类模板队列代码
template <typename T>
struct QueueNode
{
T data;
QueueNode<T>* next;
};
template <typename T>
class LinkQueue
{
public:
LinkQueue();
~LinkQueue();
bool EnQueue(const T& e);
bool DeQueue(T& e);
bool GetQueue(T& e);
bool Empty();
int Queue();
void DisplayQueue();
void ClearQueue();
private:
QueueNode<T>* m_front;
QueueNode<T>* m_rear;
int m_size;
QueueNode<T>* m_head;
};
template <typename T>
LinkQueue<T>::LinkQueue()
{
QueueNode<T>* m_head = new QueueNode<T>;
m_front = nullptr;
m_rear = nullptr;
m_head->next = m_front;
m_size = 0;
}
template <typename T>
LinkQueue<T>::~LinkQueue()
{
T k;
while (m_size > 0)
{
DeQueue(k);
}
delete m_head;
}
template <typename T>
bool LinkQueue<T>::EnQueue(const T& e)
{
QueueNode<T>* p = new QueueNode<T>;
p->data = e;
if (m_size == 0)
{
m_rear = p;
m_front = p;
m_size++;
return true;
}
if (m_size == 1)
{
m_rear = p;
m_front->next = m_rear;
m_size++;
return true;
}
else
{
QueueNode<T>* q = m_rear;
q->next = p;
m_rear = p;
m_size++;
return true;
}
}
template <typename T>
bool LinkQueue<T>::DeQueue(T& e)
{
if (m_size == 0)
{
cout << "空队列无法出队!" << endl;
return false;
}
if (m_size == 1)
{
e = m_front->data;
QueueNode<T>* p = m_front;
delete p;
m_rear = nullptr;
m_front = nullptr;
m_size--;
return true;
}
else
{
e = m_front->data;
QueueNode<T>* p = m_front;
m_front = p->next;
delete p;
m_size--;
return true;
}
}
template <typename T>
bool LinkQueue<T>::GetQueue(T& e)
{
if (m_size == 0)
{
cout << "空队列无法获取队尾元素!" << endl;
return false;
}
else
{
e = m_front->data;
return true;
}
}
template <typename T>
bool LinkQueue<T>::Empty()
{
if (m_size == 0)
{
return true;
}
else
{
return false;
}
}
template <typename T>
int LinkQueue<T>::Queue()
{
return m_size;
}
template <typename T>
void LinkQueue<T>::DisplayQueue()
{
if (m_size == 0)
{
cout << "空队列,无法扫描!" << endl;
}
else
{
QueueNode<T>* p = m_front;
for (int i = 0; i < m_size; i++)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
}
template <typename T>
void LinkQueue<T>::ClearQueue()
{
T k;
while (m_size > 0)
{
DeQueue(k);
}
delete m_head;
}
层序遍历实现代码
template <typename T>
void BinaryTree<T>::levelOrder()
{
levelOrder(root);
}
template <typename T>
void BinaryTree<T>::levelOrder(BinaryTreeNode<T>* tNode)
{
if (tNode != nullptr)
{
BinaryTreeNode<T>* tmpnode;
LinkQueue<BinaryTreeNode<T>* > lnobj;
lnobj.EnQueue(tNode);
while (!lnobj.Empty())
{
lnobj.DeQueue(tmpnode);
cout << (char)tmpnode->data << " ";
if (tmpnode->leftChild != nullptr)
{
lnobj.EnQueue(tmpnode->leftChild);
}
if (tmpnode->rightChild != nullptr)
{
lnobj.EnQueue(tmpnode->rightChild);
}
}
}
}
10.结合队列实现前序、中序、后序、层序遍历的链式二叉树实现代码
#include <iostream>
using namespace std;
template <typename T>
struct QueueNode
{
T data;
QueueNode<T>* next;
};
template <typename T>
class LinkQueue
{
public:
LinkQueue();
~LinkQueue();
bool EnQueue(const T& e);
bool DeQueue(T& e);
bool GetQueue(T& e);
bool Empty();
int Queue();
void DisplayQueue();
void ClearQueue();
private:
QueueNode<T>* m_front;
QueueNode<T>* m_rear;
int m_size;
QueueNode<T>* m_head;
};
template <typename T>
LinkQueue<T>::LinkQueue()
{
QueueNode<T>* m_head = new QueueNode<T>;
m_front = nullptr;
m_rear = nullptr;
m_head->next = m_front;
m_size = 0;
}
template <typename T>
LinkQueue<T>::~LinkQueue()
{
T k;
while (m_size > 0)
{
DeQueue(k);
}
delete m_head;
}
template <typename T>
bool LinkQueue<T>::EnQueue(const T& e)
{
QueueNode<T>* p = new QueueNode<T>;
p->data = e;
if (m_size == 0)
{
m_rear = p;
m_front = p;
m_size++;
return true;
}
if (m_size == 1)
{
m_rear = p;
m_front->next = m_rear;
m_size++;
return true;
}
else
{
QueueNode<T>* q = m_rear;
q->next = p;
m_rear = p;
m_size++;
return true;
}
}
template <typename T>
bool LinkQueue<T>::DeQueue(T& e)
{
if (m_size == 0)
{
cout << "空队列无法出队!" << endl;
return false;
}
if (m_size == 1)
{
e = m_front->data;
QueueNode<T>* p = m_front;
delete p;
m_rear = nullptr;
m_front = nullptr;
m_size--;
return true;
}
else
{
e = m_front->data;
QueueNode<T>* p = m_front;
m_front = p->next;
delete p;
m_size--;
return true;
}
}
template <typename T>
bool LinkQueue<T>::GetQueue(T& e)
{
if (m_size == 0)
{
cout << "空队列无法获取队尾元素!" << endl;
return false;
}
else
{
e = m_front->data;
return true;
}
}
template <typename T>
bool LinkQueue<T>::Empty()
{
if (m_size == 0)
{
return true;
}
else
{
return false;
}
}
template <typename T>
int LinkQueue<T>::Queue()
{
return m_size;
}
template <typename T>
void LinkQueue<T>::DisplayQueue()
{
if (m_size == 0)
{
cout << "空队列,无法扫描!" << endl;
}
else
{
QueueNode<T>* p = m_front;
for (int i = 0; i < m_size; i++)
{
cout << p->data << " ";
p = p->next;
}
cout << endl;
}
}
template <typename T>
void LinkQueue<T>::ClearQueue()
{
T k;
while (m_size > 0)
{
DeQueue(k);
}
delete m_head;
}
enum ECCHILDSIGN
{
E_Root,
E_ChildLeft,
E_ChildRight
};
template <typename T>
struct BinaryTreeNode
{
T data;
BinaryTreeNode* leftChild;
BinaryTreeNode* rightChild;
};
template <typename T>
class BinaryTree
{
public:
BinaryTree();
~BinaryTree();
BinaryTreeNode<T>* CreateNode(BinaryTreeNode<T>* parent, ECCHILDSIGN pointsign, const T& e);
void RleaseNode(BinaryTreeNode<T>* pnode);
void CreateBiTreeAccordPT(char* pstr);
void preOrder();
void inOrder();
void postOrder();
void levelOrder();
private:
BinaryTreeNode<T>* root;
void CreateBiTreeAccordPTRecu(BinaryTreeNode<T>*& tnode,char* &pstr);
void preOrder(BinaryTreeNode<T>* tNode);
void inOrder(BinaryTreeNode<T>* tNode);
void postOrder(BinaryTreeNode<T>* tNode);
void levelOrder(BinaryTreeNode<T>* tNode);
};
template<typename T>
BinaryTree<T>::BinaryTree()
{
root = nullptr;
}
template<typename T>
BinaryTree<T>::~BinaryTree()
{
RleaseNode(root);
}
template <typename T>
void BinaryTree<T>::RleaseNode(BinaryTreeNode<T>* pnode)
{
if (pnode != nullptr)
{
RleaseNode(pnode->leftChild);
RleaseNode(pnode->rightChild);
}
delete pnode;
}
template <typename T>
BinaryTreeNode<T>* BinaryTree<T>::CreateNode(BinaryTreeNode<T>* parentnode, ECCHILDSIGN pointsign, const T& e)
{
BinaryTreeNode<T>* tmpnode = new BinaryTreeNode<T>;
tmpnode->data = e;
tmpnode->leftChild = nullptr;
tmpnode->rightChild = nullptr;
if (pointsign == E_Root)
{
root = tmpnode;
}
if (pointsign == E_ChildLeft)
{
parentnode->lef