1、备用知识
个人认为利用数组实现二叉树更为简单,二叉树的增、删、改、查也更为简单。在利用数组实现中不需要专门定义一个结构体去声明左孩子与右孩子,需要注意的是数组中的左右孩子是这样定义的:
设父节点的下标为N,则左孩子的下标为:2N+1,右孩子的下标为2N+2。
此代码利用数组实现的完全二叉树插入,删除,以及遍历。
在私有数据成员包括了size(元素个数),capacity(容量),当size>=capacity时需要开辟空间,而开辟空间的大小为:
capacity = capacity+((capacity/2)>0?capacity/2:1);设置成这样主要是为了防止capacity为1或0 的情况。
具体代码如下,程序中有详细的说明:
.cpp程序
#include "stdafx.h"
#include"BinaryTree.h"
int _tmain(int argc, _TCHAR* argv[])
{
BinaryTree<int> tree;
int data[] = { 23, 54, 76, 90, 12, 33, 74, 92, 19 };
tree.InitTree(data, 9);
//for (int i = 1; i <= 10; i++)
// tree.InsertData(i);
tree.deleteData(90);
tree.travelTree(0);
return 0;
}
.h程序
#pragma once
#include<iostream>
using namespace std;
template<class T>
class BinaryTree
{
public:
BinaryTree();//构造函数
~BinaryTree();//析构函数
void InitTree(const T*pData, int size);//初始化树
void InsertData(const T& insertData);//插入节点
void deleteData(const T&data);//删除节点
int findData(const T& data);//寻找节点
void travelTree(int travelType);//遍历树
private:
void _preTravel(int index);//先序遍历
void _midTravel(int index);//中序遍历
void _lstTravel(int index);//后序遍历
T* pRoot;//数组
int size;//元素个数
int capacity;//容量
};
template<class T>
BinaryTree<T>::BinaryTree()
{
pRoot = 0;
size = 0;
capacity = 0;
}
template<class T>
BinaryTree<T>::~BinaryTree()
{
if (pRoot)
{
delete[]pRoot;
}
pRoot = 0;
size = 0;
capacity = 0;
}
template<class T>
void BinaryTree<T>::InitTree(const T*pData, int size)
{
if (pRoot)
{
delete[]pRoot;
}
if (size>0)
{
pRoot = new T[size];
memcpy(pRoot, pData, size*sizeof(T));//将数组元素赋值给pRoot
this->size = (capacity = size);
}
}
template<class T>
void BinaryTree<T>::InsertData(const T& data)
{
if (size>=capacity)//判断是否需要开辟内存空间
{
capacity = capacity + ((capacity / 2 > 0) ? capacity / 2 : 1);//需要开辟空间的大小
T* pTemp = new T[capacity];//开辟空间
if (pRoot)
{
memcpy(pTemp, pRoot, sizeof(T)* size);//将原来的数据,复制到新的内存空间上,
delete[]pRoot;//再删除原来的内存空间
}
pRoot = pTemp;
}
pRoot[size++] = data;
}
template<class T>
void BinaryTree<T>::deleteData(const T& data)
{
int index = findData(data);//要删除的节点
if (index==-1)
{
return;//没有找到
}
if (index==size-1)//数组中最后一个元素
{
pRoot[size - 1] = 0;
size--;
return;
}
memcpy(&pRoot[index], &pRoot[index + 1], (size - index - 1)*sizeof(T));//除了最后一个元素,其他的元素,全部往前挪
size--;
return;
}
template<class T>
int BinaryTree<T>::findData(const T& data)
{
for (int i = 0; i < size; i++)
{
if (pRoot[i]==data)
{
return i;
}
}
return -1;
}
template<class T>
void BinaryTree<T>::travelTree(int travelType)
{
if (travelType==0)
{
cout << "前序遍历:";
_preTravel(0);
cout << endl;
}
else if (travelType==1)
{
cout << "中序遍历:";
_midTravel(0);
cout << endl;
}
else
{
cout << "后序遍历:";
_lstTravel(0);
cout << endl;
}
}
template<class T>
void BinaryTree<T>::_preTravel(int index)
{
if (index>=size)
{
return;
}
cout << pRoot[index] << " ";
_preTravel(2 * index + 1);
_preTravel(2 * index + 2);
}
template<class T>
void BinaryTree<T>::_midTravel(int index)
{
if (index >= size)
{
return;
}
_midTravel(2 * index + 1);
cout << pRoot[index] << " ";
_midTravel(2 * index + 2);
}
template<class T>
void BinaryTree<T>::_lstTravel(int index)
{
if (index >= size)
{
return;
}
_lstTravel(2 * index + 1);
_lstTravel(2 * index + 2);
cout << pRoot[index] << " ";
}