树形结构
(一)二叉树
1.满二叉树:每个节点要么有两个子节点要么没有(要么没有孩子,有就有两个)
2.完全二叉树:只要有一层节点不是满节点,空节点的位置只能是右边的节点没有孩子
3.完美二叉树:每一层的节点都是满的,没有一个空位置
性能(时间复杂度):链表 < 普通二叉树 < 满二叉树 < 完全二叉树 < 完美二叉树
(二)编程实现
1.二叉树节点的创建
2.二叉树的遍历
(1)递归遍历:前、中、后序
- 可能出现栈溢出
(2)迭代遍历:前、中、后序、层序
- 用软件栈实现硬件栈功能,可以防止栈溢出
3.二叉树的查找与插入
C++实现
#include <iostream>
#include <stack>
#include <queue>
using namespace std;
template<class Elem>
struct BinNode{
Elem data;
BinNode<Elem>* left;
BinNode<Elem>* right;
BinNode(Elem x){
data = x;
left = right = NULL;
}
};
template<class Elem>
class BinTree{
public:
BinNode<Elem>* root;
void pre(BinNode<Elem>* root);
void ipre(BinNode<Elem>* root);
void mid(BinNode<Elem>* root);
void imid(BinNode<Elem>* root);
void pos(BinNode<Elem>* root);
void ipos(BinNode<Elem>* root);
void lay(BinNode<Elem>* root);
BinNode<Elem>* find(Elem p,BinNode<Elem>* root);
public:
BinTree(){ root = NULL; };
BinTree(Elem x){
root = new BinNode<Elem>(x);
}
~BinTree(){}
void preOrderTraversal();
void midOrderTraversal();
void posOrderTraversal();
void layOrderTraversal();
bool insert(Elem p,int LR,int data);
};
//前序递归:递和归(有去有回)
template<class Elem>
void BinTree<Elem>::pre(BinNode<Elem>* root){
if(root == NULL)
return;
cout << root->data << " ";
pre(root->left);
pre(root->right);
}
//前序迭代(用栈数据结构实现):按顺序入栈,直到走不通出栈(入栈、出栈顺序按照前序方式)
template<class Elem>
void BinTree<Elem>::ipre(BinNode<Elem>* root) {
stack<BinNode<Elem>*> st;
while(root)
{
cout << root->data << " ";
st.push(root);
root = root->left;
//不断判断节点是否为空(节点访问到头,回到前一个节点再判断)
while(root == NULL && !st.empty())
{
root = st.top();
st.pop();
root = root->right;
}
}
}
//前序遍历
template<class Elem>
void BinTree<Elem>::preOrderTraversal(){
cout << "1.递归方法:";
pre(root);
cout <<endl;
cout << "2.迭代方法:";
ipre(root);
}
//中序递归
template<class Elem>
void BinTree<Elem>::mid(BinNode<Elem>* root){
if(root == NULL)
return;
mid(root->left);
cout << root->data << " ";
mid(root->right);
}
//中序迭代
template<class Elem>
void BinTree<Elem>::imid(BinNode<Elem>* root){
stack<BinNode<Elem>*> st;
while(root)
{
st.push(root);
root = root->left;
while(root == NULL && !st.empty())
{
root = st.top();
st.pop();
cout << root->data <<" ";
root = root->right;
}
}
}
//中序遍历
template<class Elem>
void BinTree<Elem>::midOrderTraversal(){
cout << "1.递归方法:";
mid(root);
cout <<endl;
cout << "2.迭代方法:";
imid(root);
}
//后序递归
template<class Elem>
void BinTree<Elem>::pos(BinNode<Elem>* root){
if(root == NULL)
return;
pos(root->left);
pos(root->right);
cout << root->data << " ";
}
//后序迭代
template<class Elem>
void BinTree<Elem>::ipos(BinNode<Elem>* root){
stack<BinNode<Elem>*> st;
BinNode<Elem>* pre = NULL;
while(root)
{
st.push(root);
root = root->left;
while(root == NULL && !st.empty())
{
root = st.top();
if(pre == root->right || !root->right)
{
st.pop();
cout << root->data << " ";
}
pre = root;
root = root->right;
}
}
}
//后序遍历
template<class Elem>
void BinTree<Elem>::posOrderTraversal(){
cout << "1.递归方法:";
pos(root);
cout <<endl;
cout << "2.迭代方法:";
ipos(root);
}
//层序遍历(用队列实现)
template<class Elem>
void BinTree<Elem>::lay(BinNode<Elem>* root){
queue<BinNode<Elem>*> q;
q.push(root);
while(root)
{
cout << root->data << " ";
if(root->left)
q.push(root->left);
if(root->right)
q.push(root->right);
q.pop();
root = q.front();
}
}
template<class Elem>
void BinTree<Elem>::layOrderTraversal(){
lay(root);
}
template<class Elem>
BinNode<Elem>* BinTree<Elem>::find(Elem p,BinNode<Elem>* root){
BinNode<Elem>* temp = NULL;
if(root == NULL)
temp = NULL;
if(root->data == p)
return root;
temp = find(p,root->left);
return temp ? temp : find(p,root->right);
}
template<class Elem>
bool BinTree<Elem>::insert(Elem p,int LR,int data){
bool flag = false;
BinNode<Elem>* temp = find(p,root);
BinNode<Elem>* node = new BinNode<Elem>(data);
if(temp)
{
if(LR == 0)
{
if(temp->left == NULL)
{
temp->left = node;
flag = true;
}
}
if(LR == 1)
{
if(temp->right == NULL)
{
temp->right = node;
flag = true;
}
}
}
return flag;
}
int main(int argc,const char *argv[]){
BinTree<int> r(1);
/*
BinNode<int>* node1 = new BinNode<int>(2);
BinNode<int>* node2 = new BinNode<int>(3);
BinNode<int>* node3 = new BinNode<int>(4);
BinNode<int>* node4 = new BinNode<int>(5);
node1->left = node3;
node2->right = node4;
r.root->left = node1;
r.root->right = node2;
*/
r.insert(1,0,2);
r.insert(1,0,3);
r.insert(1,1,3);
r.insert(2,0,4);
r.insert(2,1,5);
r.insert(4,0,6);
cout << "前序遍历"<<endl;
r.preOrderTraversal();
cout << endl;
cout << "中序遍历"<<endl;
r.midOrderTraversal();
cout << endl;
cout << "后序遍历"<<endl;
r.posOrderTraversal();
cout << endl << endl;
cout << "层序遍历:";
r.layOrderTraversal();
return 0;
}
C实现
#include <stdio.h>
#include <stdlib.h>
#define Elem int
typedef struct BinNode{
Elem data;
struct BinNode* left;
struct BinNode* right;
}BinNode;
void init(BinNode** root,Elem data){
*root = (BinNode*)malloc(sizeof(BinNode));
(*root)->data = data;
(*root)->left = NULL;
(*root)->right = NULL;
}
BinNode* find(BinNode* root,Elem p){
BinNode* temp = NULL;
if(root == NULL)
temp = NULL;
else
{
if(root->data == p)
temp = root;
else
{
temp = find(root->left,p);
return temp ? temp:find(root->right,p);
}
}
return temp;
}
int insert(BinNode* root,Elem p,int LR,Elem data){
int flag = -1;
BinNode* temp = find(root,p);
BinNode* node = (BinNode*)malloc(sizeof(BinNode));
node->data = data;
node->left = NULL;
node->right = NULL;
if(temp == NULL)
flag = -1;
else
{
if(LR == 0)
{
if(temp->left == NULL)
{
temp->left = node;
flag = 0;
}
}
else
{
if(temp->right == NULL)
{
temp->right = node;
flag = 0;
}
}
}
return flag;
}
//前序遍历:中、左、右
void preOrderTraversal(BinNode* root){
if(root == NULL)
return;
printf("%d",root->data);
preOrderTraversal(root->left);
preOrderTraversal(root->right);
}
//中序遍历:左、中、右
void midOrderTraversal(BinNode* root){
if(root == NULL)
return;
midOrderTraversal(root->left);
printf("%d",root->data);
midOrderTraversal(root->right);
}
//后序遍历:左、右、中
void posOrderTraversal(BinNode* root){
if(root == NULL)
return;
posOrderTraversal(root->left);
posOrderTraversal(root->right);
printf("%d",root->data);
}
int main()
{
/* Write C code in this online editor and run it. */
BinNode* root;
init(&root,1);
insert(root,1,0,2);
insert(root,1,1,3);
insert(root,2,0,4);
preOrderTraversal(root);
printf("\n");
midOrderTraversal(root);
printf("\n");
posOrderTraversal(root);
return 0;
}