数组二叉树的实现
#include <iostream>
#include <cstdlib>
#include <cstdio>
// 默认的结点数量
#define MAXNODENUM (256)
// 代表不存在
#define NOTEXISTS (-1)
// 判定引用计数所引用的对象是否依旧存在
#define EXISTS(o) ((o) > 0 ? (true) : (false))
using namespace std;
class AryBitTree
{
#define DecRefCntPtr() ((m_nRefCntPtr && (*m_nRefCntPtr >= 1)) ? (--(*m_nRefCntPtr)) : NOTEXISTS)
#define IncRefCntPtr() (m_nRefCntPtr ? (++(*m_nRefCntPtr)) : NOTEXISTS)
#define LEFTCHILD(cur) ((cur) * (2) + (1))
#define RIGHTCHILD(cur) ((cur) * (2) + (2))
public:
// 无参构造函数
AryBitTree();
// 含参构造函数
AryBitTree(size_t nCapacity);
// 拷贝构造函数
AryBitTree(const AryBitTree &obj);
// 移动构造函数
AryBitTree(AryBitTree &&obj);
// 析构函数
~AryBitTree();
// 赋值运算符重载
AryBitTree &operator=(AryBitTree &obj);
// 插入结点
bool InsertNode(int iNum);
// 删除结点
bool DeleteNode(int iNum);
// 创建二叉树
bool CreateTree(const int *piArr, size_t nSize);
// 前序遍历二叉树
void PreOrderTraverse() const;
// 中序遍历二叉树
void InOrderTraverse() const;
// 后序遍历二叉树
void PostOrderTraverse() const;
// 通过值找到下标索引
int FindNode(int iNum) const;
private:
// 前序遍历内部函数
void PreOrderImpl(size_t nNodeIdx) const;
// 后续遍历内部函数
void PostOrderImpl(size_t nNodeIdx) const;
// 中序遍历内部函数
void InOrderImpl(size_t nNodeIdx) const;
private:
// 初始化二叉树
bool InitAryBitTree(size_t nCapacity = MAXNODENUM);
// 释放二叉树
void ReleaseBitTree();
private:
int *m_piTree;
size_t m_nSize;
size_t m_nCapacity;
size_t *m_nRefCntPtr;
};
AryBitTree::AryBitTree() :
m_piTree(nullptr), m_nSize(0),
m_nCapacity(MAXNODENUM), m_nRefCntPtr(nullptr)
{
// 初始化数组二叉树
InitAryBitTree();
}
AryBitTree::AryBitTree(size_t nCapacity) :
m_piTree(nullptr), m_nSize(0),
m_nCapacity(nCapacity), m_nRefCntPtr(nullptr)
{
// 初始化数组二叉树
InitAryBitTree(nCapacity);
}
AryBitTree::~AryBitTree()
{
// 释放内存
ReleaseBitTree();
}
AryBitTree::AryBitTree(const AryBitTree &obj)
{
// 如果obj自身存在问题则默认初始化后直接返回
if (!obj.m_piTree || !obj.m_nRefCntPtr)
{
InitAryBitTree();
return;
}
// 执行浅拷贝
m_nCapacity = obj.m_nCapacity;
m_nSize = obj.m_nSize;
m_piTree = obj.m_piTree;
m_nRefCntPtr = obj.m_nRefCntPtr;
// 增加引用计数
IncRefCntPtr();
}
AryBitTree::AryBitTree(AryBitTree &&obj)
{
// 执行移动操作
m_nCapacity = obj.m_nCapacity;
m_nSize = obj.m_nSize;
m_piTree = obj.m_piTree;
m_nRefCntPtr = obj.m_nRefCntPtr;
obj.m_nCapacity = 0;
obj.m_nSize = 0;
obj.m_nRefCntPtr = nullptr;
obj.m_piTree = nullptr;
}
AryBitTree & AryBitTree::operator=(AryBitTree &obj)
{
// 如果obj自身存在问题则什么也不做直接返回
if (!obj.m_piTree || !obj.m_nRefCntPtr)
{
return(*this);
}
// 降低自身引用计数, 或者直接自删除
ReleaseBitTree();
// 执行浅拷贝
m_nCapacity = obj.m_nCapacity;
m_nSize = obj.m_nSize;
m_piTree = obj.m_piTree;
m_nRefCntPtr = obj.m_nRefCntPtr;
// 增加引用计数
IncRefCntPtr();
}
bool AryBitTree::InsertNode(int iNum)
{
bool fOk = false;
int *pTmpArr = nullptr;
size_t *pnTmpRefCnt = nullptr;
size_t nTmpCap = 0;
size_t nTmpSize = 0;
do
{
// 容量满了, 需要扩容
if (m_nSize >= m_nCapacity)
{
m_nCapacity = m_nCapacity + m_nCapacity / 2;
}
// 分配新的存储空间
pTmpArr = new int[m_nCapacity];
if (!pTmpArr)
{
break;
}
// 将原树内容拷贝到新缓冲区
memcpy(pTmpArr, m_piTree, m_nSize * sizeof(m_piTree[0]));
// 保存原来的大小
nTmpSize = m_nSize;
nTmpCap = m_nCapacity;
// 降低原来的引用计数
// 引用计数为0或者不存在则销毁
ReleaseBitTree();
// 重新存入大小
m_nSize = nTmpSize;
m_nCapacity = nTmpCap;
// 插入结点
pTmpArr[m_nSize++] = iNum;
// 将剩余值置为INT_MAX代表未访问过
for (size_t nIdx = m_nSize; nIdx < m_nCapacity; ++nIdx)
{
pTmpArr[nIdx] = INT_MAX;
}
// 新的引用计数
pnTmpRefCnt = new size_t(1);
if (!pnTmpRefCnt)
{
break;
}
// 指向新树和引用计数
m_piTree = pTmpArr;
m_nRefCntPtr = pnTmpRefCnt;
fOk = true;
} while (false);
if (!fOk)
{
if (pnTmpRefCnt)
{
delete pnTmpRefCnt;
pnTmpRefCnt = nullptr;
}
if (pTmpArr)
{
delete[] pTmpArr;
pTmpArr = nullptr;
}
}
return(fOk);
}
bool AryBitTree::DeleteNode(int iNum)
{
bool fOk = false;
int iPos = NOTEXISTS;
int iLeftChild = 0;
int iRightChild = 0;
int iTmpRightChild = 0;
int iTmpLeftChild = 0;
int iLeftAndMostRight = 0;
int *piTmpAry = nullptr;
do
{
// 查找这个结点是否存在
iPos = FindNode(iNum);
if (NOTEXISTS == iPos)
{
break;
}
// 分配临时数组
piTmpAry = new int[m_nSize];
if (!piTmpAry)
{
break;
}
memcpy(piTmpAry, m_piTree, sizeof(piTmpAry[0]) * m_nSize);
for (size_t nIdx = iPos; nIdx < m_nSize - 1; ++nIdx)
{
piTmpAry[nIdx] = m_piTree[nIdx + 1];
}
piTmpAry[m_nSize - 1] = INT_MAX;
--m_nSize;
fOk = CreateTree(piTmpAry, m_nSize);
} while (false);
return(fOk);
}
bool AryBitTree::CreateTree(const int *piArr, size_t nSize)
{
bool fOk = false;
// 如果旧树存在, 并且新树的容量更大则进行扩容
if (nSize >= m_nCapacity)
{
m_nCapacity = nSize + nSize / 2;
}
// 重新初始化树, 防止内部已经存在
if (!InitAryBitTree(m_nCapacity))
{
return(false);
}
do
{
// 对树进行填充
for (size_t nIdx = 0; nIdx < m_nCapacity; ++nIdx)
{
if (nIdx < nSize)
{
m_piTree[nIdx] = piArr[nIdx];
}
else
{
m_piTree[nIdx] = INT_MAX;
}
}
m_nSize = nSize;
fOk = true;
} while (false);
return(fOk);
}
void AryBitTree::PreOrderImpl(size_t nNodeIdx) const
{
size_t nLeftChild = 0;
size_t nRightChild = 0;
if (nNodeIdx >= m_nSize)
{
return;
}
nLeftChild = LEFTCHILD(nNodeIdx);
nRightChild = RIGHTCHILD(nNodeIdx);
cout << m_piTree[nNodeIdx] << " ";
PreOrderImpl(nLeftChild);
PreOrderImpl(nRightChild);
return;
}
void AryBitTree::PostOrderImpl(size_t nNodeIdx) const
{
size_t nLeftChild = 0;
size_t nRightChild = 0;
if (nNodeIdx >= m_nSize)
{
return;
}
nLeftChild = LEFTCHILD(nNodeIdx);
nRightChild = RIGHTCHILD(nNodeIdx);
PreOrderImpl(nLeftChild);
PreOrderImpl(nRightChild);
cout << m_piTree[nNodeIdx] << " ";
return;
}
void AryBitTree::InOrderImpl(size_t nNodeIdx) const
{
size_t nLeftChild = 0;
size_t nRightChild = 0;
if (nNodeIdx >= m_nSize)
{
return;
}
nLeftChild = LEFTCHILD(nNodeIdx);
nRightChild = RIGHTCHILD(nNodeIdx);
PreOrderImpl(nLeftChild);
cout << m_piTree[nNodeIdx] << " ";
PreOrderImpl(nRightChild);
return;
}
void AryBitTree::PreOrderTraverse() const
{
if (!m_piTree || !m_nRefCntPtr || !m_nCapacity || !m_nSize)
{
return;
}
PreOrderImpl(0);
cout << endl;
return;
}
void AryBitTree::InOrderTraverse() const
{
if (!m_piTree || !m_nRefCntPtr || !m_nCapacity || !m_nSize)
{
return;
}
InOrderImpl(0);
cout << endl;
return;
}
void AryBitTree::PostOrderTraverse() const
{
if (!m_piTree || !m_nRefCntPtr || !m_nCapacity || !m_nSize)
{
return;
}
PostOrderImpl(0);
cout << endl;
return;
}
int AryBitTree::FindNode(int iNum) const
{
for (size_t nIdx = 0; nIdx < m_nSize; ++nIdx)
{
if (m_piTree[nIdx] == iNum)
{
return(nIdx);
}
}
return(NOTEXISTS);
}
bool AryBitTree::InitAryBitTree(size_t nCapacity /*= MAXNODENUM*/)
{
bool fOk = false;
size_t *pnRefCnt = nullptr;
int *piTree = nullptr;
// 如果是0代表引用计数为0需要被销毁
// 如果单纯引用计数为null可能其他内存未被销毁需要再次销毁
// 后面需要继续初始化
ReleaseBitTree();
m_nSize = 0;
m_nCapacity = nCapacity;
do
{
// 重新分配空间
piTree = new int[m_nCapacity];
if (!piTree)
{
break;
}
// 重新分配引用计数, 当前引用为1
pnRefCnt = new size_t(1);
if (!pnRefCnt)
{
break;
}
// 填充树内每个值
for (int i = 0; i < nCapacity; ++i)
{
piTree[i] = INT_MAX;
}
m_piTree = piTree;
m_nRefCntPtr = pnRefCnt;
fOk = true;
} while (0);
// 如果堆内存分配有问题则直接释放
if (!fOk)
{
if (piTree)
{
delete[] piTree;
piTree = nullptr;
}
if (pnRefCnt)
{
delete pnRefCnt;
pnRefCnt = nullptr;
}
}
return(fOk);
}
void AryBitTree::ReleaseBitTree()
{
// 如果引用计数大于1则代表超过1个对象在引用, 这时
// 直接降低引用计数后返回
int iRet = 0;
// 降低引用计数
iRet = DecRefCntPtr();
if (iRet != NOTEXISTS && iRet)
{
return;
}
// 释放
if (m_piTree)
{
delete[] m_piTree;
m_piTree = nullptr;
}
if (m_nRefCntPtr)
{
delete m_nRefCntPtr;
m_nRefCntPtr = nullptr;
}
m_nCapacity = m_nSize = 0;
}
void TestFunc()
{
AryBitTree bin;
int iArr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
bin.CreateTree(iArr, sizeof(iArr) / sizeof(iArr[0]));
bin.PreOrderTraverse();
bin.InOrderTraverse();
bin.PostOrderTraverse();
bin.InsertNode(11);
bin.PreOrderTraverse();
bin.InsertNode(15);
bin.PreOrderTraverse();
bin.DeleteNode(4);
bin.PreOrderTraverse();
bin.DeleteNode(1);
bin.DeleteNode(2);
bin.DeleteNode(5);
bin.DeleteNode(11);
bin.DeleteNode(15);
bin.DeleteNode(3);
bin.DeleteNode(6);
bin.DeleteNode(7);
bin.PreOrderTraverse();
// 拷贝构造
AryBitTree bin1 = bin;
cout << "拷贝后的内容" << endl;
bin1.PreOrderTraverse();
AryBitTree bin2;
bin2.CreateTree(iArr, 5);
cout << "bin2原来的内容: ";
bin2.PreOrderTraverse();
bin2 = bin;
cout << "bin2现在的内容: ";
bin2.PreOrderTraverse();
AryBitTree bin3 = static_cast<AryBitTree&&>(bin2);
}
int main()
{
TestFunc();
system("pause");
return (0);
}
(完)