二叉树或为空,或是由一个根节点加上两棵分别称为左子树、右子树互补相交的二叉树组成。
存储结构:(数据和关系缺一不可)
1、顺序存储结构:从上到下,从左到右依次编号(数组的下标)。可根据下标编号恢复出树,但缺点是普通树在极端条件下数组中的空缺较多。
2、链式存储结构:这种存储方案设计出了结构,分为二叉链表和三叉链表两种,前者存储密度较高,但不利于查找双亲。
3、静态结构:以表格的形式体现,包括data、parent、leftChild、rightChild。
考点:1、创建 2、非递归的前中后序遍历 3、检查树是否是完全二叉树
完整代码如下:
typedef char ElemType;
typedef struct BtNode
{
BtNode* leftchild;
BtNode* rightchild;
ElemType data;
}BtNode,*BinaryTree;
BtNode* Buynode()
{
BtNode* s = (BtNode*)malloc(sizeof(BtNode));
if (nullptr == s) exit(1);
memset(s, 0, sizeof(BtNode));
return s;
}
void PreOrder(BtNode* ptr)
{
if (ptr != nullptr)
{
cout << ptr->data << " ";
PreOrder(ptr->leftchild);
PreOrder(ptr->rightchild);
}
}
void InOrder(BtNode* ptr)
{
if (ptr != nullptr)
{
InOrder(ptr->leftchild);
cout << ptr->data << " ";
InOrder(ptr->rightchild);
}
}
void PastOrder(BtNode* ptr)
{
if (ptr != nullptr)
{
PastOrder(ptr->leftchild);
PastOrder(ptr->rightchild);
cout << ptr->data << " ";
}
}
int FindIs(const char*is, int n, ElemType val)
{
int pos = -1;
for (int i = 0; i < n; ++i)
{
if (is[i] == val)
{
pos = i;
break;
}
}
return pos;
}
BtNode* CreatePI(const char*pr, const char* is, int n)
{
BtNode* s = nullptr;
if (n > 0)
{
s = Buynode();
s->data = pr[0];
int pos = FindIs(is, n, pr[0]);
if (pos == -1) exit(1);
s->leftchild = CreatePI(pr+1,is,pos);
s->rightchild = CreatePI(pr+pos+1,is+pos+1,n-pos-1);
}
return s;
}
BtNode* CreateTreePI(const char*pr, const char* is)
{
if (pr == nullptr || is == nullptr) return nullptr;
int pn = strlen(pr);
int in = strlen(is);
if (pn != in) return nullptr;
return CreatePI(pr, is, pn);
}
BtNode* CreateIP(const char*is, const char*ps,int n)
{
BtNode* s = nullptr;
if (n > 0)
{
s = Buynode();
s->data = ps[n-1];
int pos = FindIs(is, n, ps[n - 1]);
if (pos == -1) exit(1);
s->leftchild=CreateIP(is,ps,pos);
s->rightchild=CreateIP(is+pos+1,ps+pos,n-pos-1);
}
return s;
}
BtNode* CreateTreeIP(const char*is, const char*ps)
{
if (is == nullptr || ps == nullptr) return nullptr;
int in = strlen(is);
int pn = strlen(ps);
if (in != pn) return nullptr;
return CreateIP(is, ps, in);
}
//前序非递归遍历,用栈实现
void NicePreOrder(BtNode* ptr)
{
if (ptr == nullptr)return;
std::stack<BtNode*>st;
st.push(ptr);
while (!st.empty())
{
ptr = st.top(); st.pop();
cout << ptr->data << " ";
//打印根后先压右边,后弹栈
if (ptr->rightchild!= nullptr)
{
st.push(ptr->rightchild);
}
if (ptr->leftchild!= nullptr)
{
st.push(ptr->leftchild);
}
}
cout << endl;
}
//中序非递归遍历,用栈实现
void NiceInOrder(BtNode* ptr)
{
if (ptr == nullptr)return;
std::stack<BtNode*>st;
//找最左
while (ptr != nullptr || !st.empty())
{
while (ptr != nullptr)
{
st.push(ptr);
ptr = ptr->leftchild;
}
ptr = st.top(); st.pop();
cout << ptr->data << " ";
ptr = ptr->rightchild;
}
cout << endl;
}
//后序非递归遍历,用栈实现,
//加标志指针判断有没有遍历右边
void NicePastOrder(BtNode* ptr)
{
if (ptr == nullptr)return;
BtNode* tag = nullptr;
std::stack<BtNode*>st;
//找最左
while (ptr != nullptr || !st.empty())
{
while (ptr != nullptr)
{
st.push(ptr);
ptr = ptr->leftchild;
}
ptr = st.top(); st.pop();
//取出来后不一定可以打印
if (ptr->rightchild == nullptr || ptr->rightchild)
{
cout << ptr->data << " ";
tag = ptr;
ptr = nullptr;
}
else
{
st.push(ptr);
ptr = ptr->rightchild;
}
}
cout << endl;
}
//层次遍历
void NiceLevelOrder(BtNode* ptr)
{
if (ptr == nullptr)return;
std::queue<BtNode*>qu;
qu.push(ptr);
while (!qu.empty())
{
BtNode* p = qu.front();
qu.pop();
cout << p->data << " ";
if (p->leftchild != nullptr)
{
qu.push(p->leftchild);
}
if (p->rightchild != nullptr)
{
qu.push(p->rightchild);
}
}
cout << endl;
}
//Z型打印
void NiceZLOrder(BtNode* ptr)
{
if (ptr == nullptr) return;
std::stack<BtNode*> sta;
std::stack<BtNode*> stb;
sta.push(ptr);
while (!sta.empty() || !stb.empty())
{
while (!sta.empty())
{
ptr = sta.top(); sta.pop();
cout << ptr->data << " ";
if (ptr->leftchild != nullptr)
{
stb.push(ptr->leftchild);
}
if (ptr->rightchild != nullptr)
{
stb.push(ptr->rightchild);
}
}
while (!stb.empty())
{
ptr = stb.top(); stb.pop();
cout << ptr->data << " ";
if (ptr->rightchild != nullptr)
{
sta.push(ptr->rightchild);
}
if (ptr->leftchild != nullptr)
{
sta.push(ptr->leftchild);
}
}
}
cout << endl;
}
//获得节点个数
//1、前中后续遍历,不打印,次数加一,递归方法使用全局变量
//2、分治策略,每一棵子树都是左子树加右子树加根的个数
int GetSize(BtNode* ptr)
{
if (ptr== nullptr)
{
return 0;
}
else
{
return GetSize(ptr->leftchild) + GetSize(ptr->rightchild) + 1;
}
}
//获得树的高度
//分治策略,选择左子树和右子树较高的加1
int GetDepth(BtNode* ptr)
{
if (ptr == nullptr)
{
return 0;
}
else
{
return max(GetDepth(ptr->leftchild), GetDepth(ptr->rightchild)) + 1;
}
}
//非递归求树高,和层次遍历类似
int GetNiceDepth(BtNode* ptr)
{
int sum = 0;
if (ptr == nullptr) return sum;
std::queue<BtNode*>qu;
qu.push(ptr);
while (!qu.empty())
{
int n = qu.size();
while (n--)
{
ptr = qu.front(); qu.pop();
if (ptr->leftchild != nullptr) qu.push(ptr->leftchild);
if (ptr->rightchild != nullptr) qu.push(ptr->rightchild);
}
sum += 1;
}
return sum;
}
//是否是满二叉树,和层次遍历有关
bool Is_Full(BtNode* ptr)
{
int he = 1;
bool res = true;
if (ptr == nullptr) return res;
std::queue<BtNode*>qu;
qu.push(ptr);
while (!qu.empty())
{
int n = qu.size();
if (n != he)
{
res=false;
break;
}
while (n--)
{
ptr = qu.front(); qu.pop();
if (ptr->leftchild != nullptr) qu.push(ptr->leftchild);
if (ptr->rightchild != nullptr) qu.push(ptr->rightchild);
}
he+=he;//1+1=2;2+2=4;4+4=8
}
return res;
}
//是否是完全二叉树,和层次遍历有关
//将空的补在后面
//队列到了一个第一个空,如果后面全是空,就是完全二叉树
bool Is_Comp(BtNode* ptr)
{
bool res = true;
if (ptr == nullptr) return res;
std::queue<BtNode*> qu;
qu.push(ptr);
while (!qu.empty())
{
ptr = qu.front();
qu.pop();
if (ptr == nullptr) break;
qu.push(ptr->leftchild);//不管是不是空都入栈
qu.push(ptr->rightchild);
}
//从队列第一个是nullptr的开始
while (!qu.empty())
{
ptr = qu.front();
if (ptr != nullptr)
{
res = false;
break;
}
}
return res;
}
//在树中查询元素,如果找到返回含有该元素的地址
//没有找到返回空指针
//非递归:将前序、中序、后序或层次遍历的打印变成比较
//递归:注意要把值接回来,用变量接,直接return的话后面不执行
BtNode* FindValue(BtNode* ptr, ElemType val)
{
if (ptr == nullptr || ptr->data == val)
{
return ptr;
}
else
{
BtNode* p = FindValue(ptr->leftchild, val);
//如果左边没找到,进入右边
if (p == nullptr)
{
p = FindValue(ptr->rightchild, val);
}
return p;
}
}
//查找某节点的双亲节点
BtNode* Parent(BtNode*ptr, BtNode*child)
{
if (ptr == nullptr || ptr->leftchild == child || ptr->rightchild == child)
{
return ptr;
}
else
{
BtNode*p = Parent(ptr->leftchild, child);
if (p == nullptr)
{
p = Parent(ptr->rightchild, child);
}
return p;
}
}
BtNode* FindParent(BtNode*ptr, BtNode*child)
{
if (ptr == nullptr || child == nullptr||ptr==child)
{
return nullptr;
}
else
{
return Parent(ptr, child);
}
}
//最近的公共双亲节点,leetcode33
BtNode* FindNParent(BtNode* ptr,BtNode* first,BtNode* second)
{
}
int main()
{
BinaryTree root = nullptr;
char pr[] = { "ABCDEFGH" };
char is[] = { "CBEDFAGH" };
char ps[] = { "CEFDBHGA" };
//root = CreateTreePI(pr, is);//根据前序和中序构建树
root = CreateTreePI(is,ps);//根据前序和中序构建树
PreOrder(root);cout << endl;
InOrder(root); cout << endl;
PastOrder(root); cout << endl;
NiceInOrder(root);
NicePastOrder(root);
return 0;
}