1.算法 二叉树
二叉树分满二叉树、完全二叉树、平衡二叉树、红黑树。
满二叉树:除最后一层外,每一层都有两个节点。
完全二叉树:除最后一层外,每一层节点数都达到最大值,且缺少最右边的节点
平衡二叉树:本质上是二叉树查找树,只不过是为了防止退化成链表加入了平衡,也就是平衡因子保证是一个平衡的二叉树。
红黑树:本质上也是二叉查找树,加入了红黑节点保证其实平衡的。
二叉树:
(1)遍历方式
前序遍历、中序遍历、后序遍历、层次遍历。
都是应该递归的方式。应用退栈的方式来进行遍历。
头文件:
#ifndef _DTREE_
#define _DTREE_
#include "head.h"
#include <vector>
typedef struct ST_Dtree
{
int data;
ST_Dtree *right;
ST_Dtree *left;
};
class Dtree
{
public:
Dtree();
~Dtree();
void Begin();
//创建二叉树
ST_Dtree* createDTree(int &pos, int *str, int len);
//求二叉树的 高度
int DTreeDepth(ST_Dtree* node);
//求二叉树节点个数
int DTreeNodeCount(ST_Dtree* node);
//四种遍历方式
//前序遍历
void Forpre(ST_Dtree* node);
//中序遍历
void ForMid(ST_Dtree* node);
//后序遍历
void ForLast(ST_Dtree* node);
//层次遍历
void ForLevel();
private:
ST_Dtree *root;
};
#endif
实现:
#include "DTree.h"
Dtree::Dtree()
{}
Dtree::~Dtree()
{}
void Dtree::Begin()
{
int pos = -1;
char str[10] = {0};
int num[] = {1,2,4,8,0,0,9,0,0,5,10,0,0,11,0,0,3,6,12,0,0,13,0,0,7,14,0,0,15,0,0};
int len = sizeof(num)/sizeof(num[0]);
//创建二叉树
root = createDTree(pos, num, len);
//四种遍历方式
//前序遍历
Forpre(root);
//中序遍历
ForMid(root);
//后序遍历
ForLast(root);
//层次遍历
ForLevel();
int hight = DTreeDepth(root);
int count = DTreeNodeCount(root);
return;
}
ST_Dtree* Dtree::createDTree(int &pos, int* str, int len)
{
pos++;
ST_Dtree* node;
node = (ST_Dtree*)malloc(sizeof(ST_Dtree));
memset(node, 0, sizeof(ST_Dtree));
if(str[pos] == 0)
{
return NULL;
}
if(pos > len)
{
return NULL;
}
node->data = str[pos];
node->left = createDTree(pos, str, len);
node->right = createDTree(pos, str, len);
return node;
}
//前序遍历
void Dtree::Forpre(ST_Dtree* node)
{
if(node == NULL)
{
return ;
}
printf("%d\n", node->data);
Forpre(node->left);
Forpre(node->right);
}
//中序遍历
void Dtree::ForMid(ST_Dtree* node)
{
if(node == NULL)
{
return ;
}
ForMid(node->left);
printf("%d\n", node->data);
ForMid(node->right);
}
//后序遍历
void Dtree::ForLast(ST_Dtree* node)
{
if(node == NULL)
{
return ;
}
ForLast(node->left);
ForLast(node->right);
printf("%d\n", node->data);
}
int Dtree::DTreeDepth(ST_Dtree* node)
{
if(node == NULL)
{
return 0;
}
int left = DTreeDepth(node->left);
int right = DTreeDepth(node->right);
return max(left, right) + 1;
}
void Dtree::ForLevel()
{
//用队列和用vector 实质上是等价的。原理都是把左右元素压入容器中,然后删除第一个元素。达到遍历二叉树的目的。
if(root != NULL)
{
//容器用结构体ST_Dtree,能够更好的判断什么时候结束程序
vector<ST_Dtree*> vec;
vec.push_back(root);
while(!vec.empty())
{
//获取结构体信息
ST_Dtree *temp = vec[0];
//从左到右依次打印节点
printf("%d\n", vec[0]->data);
//删除容器第一个节点
vec.erase(vec.begin());
//保存接下来的节点,依次来进行遍历
if(temp->left != NULL)
{
vec.push_back(temp->left);
}
//保存接下来的节点,依次进行遍历
if(temp->right != NULL)
{
vec.push_back(temp->right);
}
}
}
}
int Dtree::DTreeNodeCount(ST_Dtree* node)
{
if(node == NULL)
{
return 0;
}
int left = DTreeNodeCount(node->left);
int right = DTreeNodeCount(node->right);
int count = left + right + 1;
return count;
}