总目录
(一) 基础知识
树的深度:任意节点到根节点的唯一路径长
树的高度:从某一叶节点数到它的根节点的最长路径长;
(二) 相关存储结构
① 数组存储(需要数学关系确定数据之间的关系)
② 链式存储
1.二叉链式存储
2.三叉链式存储
③静态存储
以下目录需要
头文件:
#include<iostream>
using namespace std;
#include<stack>
#include<queue>
#include<stdlib.h>
二叉树节点结构体:
typedef struct BtNode
{
struct BtNode* leftchild;
struct BtNode* rightchild;
int data;
}BtNode,*BinartTree;
构建一个二叉树节点
BtNode* BuyNode()
{
BtNode* s=(BtNode*)malloc(sizeof(BtNode));
if(s==NULL) {exit(1);}
memset(s,0,sizeof(BtNode));
return s;
}
(三) 递归遍历二叉树
1.先序递归遍历
先序遍历:根左右----->先根再左子树再右子树
例如:
void PreOrder(BtNode *ptr)
{
if(ptr!=NULL)
{
cout<<" "<<ptr->data;
PreOrder(ptr->leftchild);
PreOrder(ptr->rightchild);
}
}
2.中序递归遍历
中序遍历:左根右----->先左子树再根再右子树
例如:
void InOrder(BtNode *ptr)
{
if(ptr!=NULL)
{
InOrder(ptr->leftchild);
cout<<" "<<ptr->data;
InOrder(ptr->rightchild);
}
}
3.后序递归遍历
后序遍历:左右根----->先左子树再右子树再根
例如:
void PastOrder(BtNode *ptr)
{
if(ptr!=NULL)
{
PastOrder(ptr->leftchild);
PastOrder(ptr->rightchild);
cout<<" "<<ptr->data;
}
}
(四) 构建二叉树
1.字符串构建
BtNode* CreateBtStr(const char*& str)
{
BtNode* s = NULL;
if (*str != '#')
{
s = BuyNode();
s->data = *str;
s->leftchild = CreateBtStr(++str);
s->rightchild = CreateBtStr(++str);
}
return s;
}
BtNode* CreateTreeStr(const char* str)
{
if (str == NULL || strlen(str) <= 0)
{
cout << "无字符串来构建二叉树" << endl;
return NULL;
}
else
{
return CreateBtStr(str);
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 先序:";
PreOrder(root);
cout << endl;
cout << " 中序:";
InOrder(root);
cout << endl;
cout << " 后序:";
PastOrder(root);
cout << endl;
return 0;
}
运行结果:
注意:CreateBtStr(const char * &str)中参数str前一定要加&符,如果不加结果如下
造成这样结果的原因是:
总结:如果不加&每一次递归时 都会有不一样的str,因此无法将字符串全部遍历;加了&后 每次递归的str都是同一个值
2.用先序中序构建(面试常考)
int FindPos(const char* istr,const char ch)
{
int len = strlen(istr);
int pos = -1;
for (int i = 0; i < len; i++)
{
if (istr[i] == ch)
{
pos = i;
break;
}
}
return pos;
}
BtNode* CreateBTreePI(const char* pstr, const char* istr, int n)
{
BtNode* s = NULL;
if (n > 0)
{
s = BuyNode();
s->data = pstr[0];
int pos = FindPos(istr, pstr[0]);
s->leftchild = CreateBTreePI(pstr + 1, istr, pos);
s->rightchild = CreateBTreePI(pstr + pos + 1, istr + pos + 1, n - pos - 1);
}
return s;
}
主函数:
int main()
{
const char* pstr = { "ABCDEFGH" };
cout << " pstr = " << pstr;
cout << endl;
const char* istr = { "CBEDFAGH" };
cout << " istr = " << istr;
cout << endl;
BinaryTree root = CreateBTreePI(pstr, istr, strlen(pstr));
if (root != NULL)
{
cout << " (二叉树构建完成) " << endl;
}
cout << " 先序遍历结果: ";
PreOrder(root);
cout << endl;
cout << " 中序遍历结果: ";
InOrder(root);
cout << endl;
return 0;
}
运行结果:
2.用中序后序构建
int FindPos(const char* istr,const char ch)
{
int len = strlen(istr);
int pos = -1;
for (int i = 0; i < len; i++)
{
if (istr[i] == ch)
{
pos = i;
break;
}
}
return pos;
}
BtNode* CreateBTreeIL(const char* istr, const char* lstr, int n)
{
BtNode* s = NULL;
if (n > 0)
{
s = BuyNode();
s->data = lstr[n-1];
int pos = FindPos(istr, lstr[n-1]);
s->leftchild = CreateBTreeIL(istr, lstr, pos);
s->rightchild = CreateBTreeIL(istr + pos + 1, lstr + pos, n - pos - 1);
}
return s;
}
主函数:
int main()
{
const char* istr = { "CBEDFAGH" };
cout << " istr = " << istr;
cout << endl;
const char* lstr = { "CEFDBHGA" };
cout << " lstr = " << lstr;
cout << endl;
BinaryTree root = CreateBTreeIL(istr, lstr, strlen(lstr));
if (root != NULL)
{
cout << " (二叉树构建完成) " << endl;
}
cout << " 中序遍历结果: ";
InOrder(root);
cout << endl;
cout << " 后序遍历结果: ";
PastOrder(root);
cout << endl;
return 0;
}
运行结果:
(五) 非递归遍历二叉树
1.先序非递归遍历
(需要使用栈)
注意:需要先入右孩子再入左孩子,这样出栈才能达到先左后右(先进后出)
void NicePreOrder(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空";
return;
}
std::stack<BtNode*> st;
st.push(ptr);
while (!st.empty())
{
ptr = st.top();
cout << " " << ptr->data;
st.pop();
if (ptr->rightchild != NULL)
{
st.push(ptr->rightchild);
}
if(ptr->leftchild!=NULL)
{
st.push(ptr->leftchild);
}
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 非递归先序:";
NicePreOrder(root);
cout << endl;
return 0;
}
运行结果:
2.中序非递归遍历
第一种方法
(需要使用栈)
void NiceInOrder(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空";
return;
}
std::stack<BtNode*> st;
while (!st.empty() || ptr != NULL)
{
while (ptr != NULL)
{
st.push(ptr);
ptr = ptr->leftchild;
}
ptr = st.top();
cout << " " << ptr->data;
st.pop();
ptr = ptr->rightchild;
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 非递归中序:";
NiceInOrder(root);
cout << endl;
return 0;
}
运行结果:
第二种方法
(需要使用栈)
需要额外定义一个结构体来存放指向二叉树节点的指针和保存出栈次数的整数
struct StkNode
{
BtNode* pnode;
int popnum;
};
void NiceInOrder_2(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空" << endl;
}
std::stack<StkNode> st;
st.push(StkNode{ ptr,0 });
while (!st.empty())
{
StkNode node = st.top();
st.pop();
int t = ++node.popnum;
if (t == 2)
{
cout << " " << node.pnode->data;
if (node.pnode->rightchild != NULL)
{
st.push(StkNode{ node.pnode->rightchild,0 });
}
}
else
{
st.push(node);
if (t == 1 && node.pnode->leftchild != NULL)
{
st.push(StkNode{ node.pnode->leftchild,0 });
}
}
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 第二种 非递归中序:";
NiceInOrder_2(root);
cout << endl;
return 0;
}
运行结果:
3.后序非递归遍历
第一种方法
(需要使用栈)
void NicePastOrder(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空";
return;
}
std::stack<BtNode*> st;
BtNode* tag=NULL;
while (ptr != NULL || !st.empty())
{
while (ptr != NULL)
{
st.push(ptr);
ptr = ptr->leftchild;
}
ptr = st.top();
st.pop();
if (ptr->rightchild == NULL || ptr->rightchild == tag)
{
cout << " " << ptr->data;
tag = ptr;
ptr = NULL;
}
else
{
st.push(ptr);
ptr = ptr->rightchild;
}
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 第一种 非递归后序:";
NicePastOrder(root);
cout << endl;
return 0;
}
运行结果:
第二种方法
需要额外定义一个结构体来存放指向二叉树节点的指针和保存出栈次数的整数
struct StkNode
{
BtNode* pnode;
int popnum;
};
void NicePastOrder_2(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空";
return;
}
std::stack<StkNode> st;
st.push(StkNode{ ptr,0 });
while (!st.empty())
{
StkNode node = st.top();
st.pop();
int t = ++node.popnum;
if (t == 3)
{
cout << " " << node.pnode->data;
}
else
{
st.push(node);
if (t == 1 && node.pnode->leftchild != NULL)
{
st.push(StkNode{ node.pnode->leftchild,0 });
}
else if (t == 2 && node.pnode->rightchild != NULL)
{
st.push(StkNode{ node.pnode->rightchild,0 });
}
}
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 第二种 非递归后序:";
NicePastOrder_2(root);
cout << endl;
return 0;
}
运行结果:
(六)层次遍历二叉树
(需要使用队列)
void LevelOrder(BtNode* ptr)
{
if (ptr == NULL)
{
cout << "二叉树为空" << endl;
}
std::queue<BtNode*> qu;
qu.push(ptr);
while (!qu.empty())
{
ptr = qu.front();
cout << " " << ptr->data;
qu.pop();
if (ptr->leftchild != NULL)
{
qu.push(ptr->leftchild);
}
if (ptr->rightchild != NULL)
{
qu.push(ptr->rightchild);
}
}
}
主函数:
int main()
{
const char* str = "ABC##DE##F##G#H##";
BinaryTree root = CreateTreeStr(str);
cout << " 层次遍历:";
LevelOrder(root);
return 0;
}
运行结果: