第七节课:9.3:二叉树
一、二叉树
1.概念:
是树的一种,其存储结构及其算法都较为简单,因此二叉树显得特别重要
每一层的节点最多只有两个子节点的树;
子树有左子树和右子树之分;
注意:二叉树可以只有右子树没有左子树,但是完全二叉树不可以
2.分类:
分为五类:
3.特性:
1.每一层的节点数不能超过2的(i-1)次方个
2.深度为k的树的节点数最大为2的k次方-1个
3.一个节点的度只能为0,1,2
4.二叉树的子树有左右之分
5.任意一课二叉树,度为2的节点数为n,则度为0的节点数为n+1;
二、满二叉树
1.概念:
当思考到用什么结构存储二叉树时,假设存储如下图所示的二叉树
由于其下标的特性以及每层最大两个节点,选用数组作为数据结构存储,但是这样会造成空间浪费,中间有些位置空出来了如下图所示
造成空间浪费;所以,引入满二叉树:
第i层的节点数必须满足:2的(i-1)次方,除了根节点之外,每一层的节点数都饱和为·两个;
2.特性:
1.第i层的节点数为2的(i-1)次方;
2.深度为k的满二叉树的的节点个数为:2的k次方-1个;
3.最后一层为叶节点,一个节点的度只能为2或者0;
三、完全二叉树
1.概念:
由于实际应用时,元素的个数大部分情况不满足节点个数的要求,于是就有了完全二叉树;
从满二叉树的叶节点的那一层开始从最右边的节点开始删除若干节点,也可以不删;
2.特性:
1.除了最后一层,其他层的节点个数仍满二叉树的个数的特性;
(也就是说不能够插入新的节点了)
2.用顺序表来存储,左子树的下标为奇数,右子树的下标为偶数
3.父节点的下标为i,则左子树下标为2*i + 1
;右子树的下标为2* i + 2
;
4.左子树或者是右子树的下标为i,他们的父节点的下标为:(i - 1)/2
5.若没有左子树则必然没有右子树
6.根节点下标默认为0
3.二叉树的遍历方式:
先序:NLR ;中序 :LNR;后序:LRN;
4.code:
#pragma once
enum choose {FIRST,MID,LAST};
template < class T>
class CMy_binary_tree
{
T* pBuff;
int len;
int size;
public:
CMy_binary_tree();
~CMy_binary_tree();
void clear();
public:
void insert(T const& insert_data);//只能在最后一个节点的位置出插入
bool find(T const& find_data);
void del();//只能删除最后一个节点
void init_tree(int length);
public://区别于顺序表的操作,表明这一个数据结构是二叉树
T get_left_child(T const& pos_data) const;
T get_right_child(T const& pos_data) const;
T get_parent(T const& pos_data) const;
void print_FISRT_MID_LAST(int choose_FISRT_MID_LAST)const;
private:
void amplify_scale();
int _find(T const& find_data) const;
void print_NLR(int index) const;
void print_LNR(int index) const;
void print_LRN(int index) const;
};
template <class T>
void CMy_binary_tree<T>::print_FISRT_MID_LAST(int choose_FISRT_MID_LAST)const
{
switch (choose_FISRT_MID_LAST)
{
case FIRST:
print_NLR(0);
printf("\n");
break;
case MID:
print_LNR(0);
printf("\n");
break;
case LAST:
print_LRN(0);
printf("\n");
break;
default:
printf("printf error!");
break;
}
}
template <class T>
void CMy_binary_tree<T>::print_NLR(int index) const
{
if (index <= len - 1)
{
printf("%d ", pBuff[index]);
print_NLR(2 * index + 1);
print_NLR(2 * index + 2);
}
}
template <class T>
void CMy_binary_tree<T>::print_LNR(int index) const
{
if (index <= len - 1)
{
print_LNR(2 * index + 1);
printf("%d ", pBuff[index]);
print_LNR(2 * index + 2);
}
}
template <class T>
void CMy_binary_tree<T>::print_LRN(int index) const
{
if (index <= len - 1)
{
print_LRN(2 * index + 1);
print_LRN(2 * index + 2);
printf("%d ", pBuff[index]);
}
}
template <class T>
int CMy_binary_tree<T>::_find(T const& find_data) const
{
if (pBuff == nullptr) return -1;
//数组的遍历:
for (int i = 0; i < len; i++)
{
if (find_data == pBuff[i])
return i;
}
return -1;
}
template <class T>
T CMy_binary_tree<T>::get_left_child(T const& pos_data) const
{
int index = _find(pos_data);
if (index == -1) return -1;
return pBuff[2 * index + 1];
}
template <class T>
T CMy_binary_tree<T>::get_right_child(T const& pos_data) const
{
int index = _find(pos_data);
if (index == -1) return -1;
return pBuff[2 * index + 2];
}
template <class T>
T CMy_binary_tree<T>::get_parent(T const& pos_data) const
{
int index = _find(pos_data);
if (index == -1) return -1;
return pBuff[(index - 1) / 2];
}
template <class T>
void CMy_binary_tree<T>::init_tree(int length)
{
//先清空
clear();
size = len = length;
pBuff = new T[size];
for (int i = 0; i < length; i++)
{
pBuff[i] = 0;
}
}
template <class T>
void CMy_binary_tree<T>::amplify_scale()
{
if (len >= size)
{
//内存重分配:
size = size + ((size >> 1) < 1 ? 1 : (size >> 1));//半倍扩容:
T* tempBuff = new T[size];
for (int i = 0; i < len; i++)//深拷贝
{
tempBuff[i] = pBuff[i];
}
delete[]pBuff;
pBuff = tempBuff;
tempBuff = nullptr;
}
return;
}
template <class T>
bool CMy_binary_tree<T>::find(T const& find_data)
{
if (_find(find_data) == -1)
return false;
return true;
}
template <class T>
void CMy_binary_tree<T>::del()
{
len--;
}
template <class T>
void CMy_binary_tree<T>::insert(T const& insert_data)
{
//没有根节点:
if (pBuff == nullptr)
{
amplify_scale();//扩容
pBuff[0] = insert_data;
}
else
{
amplify_scale();//扩容
pBuff[len] = insert_data;
}
len++;
}
template <class T>
void CMy_binary_tree<T>::clear()
{
if (pBuff == nullptr) return;
delete[] pBuff;
pBuff = nullptr;
len = size = 0;
}
template <class T>
CMy_binary_tree<T>::CMy_binary_tree()
{
pBuff = nullptr;
len = size = 0;
}
template <class T>
CMy_binary_tree<T>::~CMy_binary_tree()
{
clear();
}