有需要的小伙伴可以借鉴代码思路,但是不要copy~
main函数
随便调试的函数,大家根据需要自己调试函数哈~
#include "BiTree.cpp"
#include <iostream>
using namespace std;
#define NodesLength 27
int main(int argc, const char * argv[]) {
// char preOrder[NodesLength] = {'A', 'B', 'D', 'C', 'E', 'F'};
// char inOrder[NodesLength] = { 'D', 'B', 'A', 'E', 'C', 'F'};
// BiTree<char> T(preOrder, inOrder, NodesLength);
// T.PostOrder();
BiTree<char> T;
cout << T.GetNodesNumberOfKthLevle(3) << endl;
cout << T.GetLeafNodesNumberOfKthLevel(3);
T.PrintNodesOfKthLevel(3);
cout << endl;
T.PrintLeafNodesOfKthLevel(3);
return 0;
}
.h 文件
#ifndef BiTree_hpp
#define BiTree_hpp
#include <stdio.h>
#include <stdlib.h>
template <class ElemType>
struct BiNode{
ElemType data;
BiNode <ElemType> *lchild,*rchild;
};
template<class ElemType>
class BiTree{
private:
BiNode<ElemType> *root;
BiNode<ElemType> *Creat(BiNode<ElemType> *bt);
void Release(BiNode<ElemType> *bt);
void PreOrder(BiNode<ElemType> *bt);
void InOrder(BiNode<ElemType> *bt);
void PostOrder(BiNode<ElemType> *bt);
void LevelOrder(BiNode<ElemType> *bt);
int Depth(BiNode<ElemType> *bt);
int Count(BiNode<ElemType> *bt);
int CountLeaf(BiNode<ElemType> *bt);
void PrintLeaf(BiNode<ElemType> *bt);
int SmallestDepth(BiNode<ElemType> *bt);
int IsCompleteBiTree(BiNode<ElemType> *bt);
int IsCheck(BiNode<ElemType> *lchild , BiNode<ElemType> *rchild);
int IsStructureSymmetric(BiNode<ElemType> *bt);
int IsL_R_Check(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild);
//二叉树第k层的结点个数和叶子结点个数
int GetNodesNumberOfKthLevle(BiNode<ElemType> *bt,int k);
int GetLeafNodesNumberOfKthLevel(BiNode<ElemType> *bt,int k);
//打印二叉树第k层的结点和叶子结点
void PrintNodesOfKthLevel(BiNode<ElemType> *bt,int k);
void PrintLeafNodesOfKthLevel(BiNode<ElemType> *bt,int k);
public:
BiTree(){root = Creat(root);}
~BiTree(){
Release(root);
}
void PreOrder(){
PreOrder(root);
}
void InOrder(){
InOrder(root);
}
void PostOrder(){
PostOrder(root);
}
void LevelOrder(){
LevelOrder(root);
}
int Depth(){
return Depth(root);
}
int Count(){
return Count(root);
}
int CountLeaf(){
return CountLeaf(root);
}
void PrintLeaf(){
PrintLeaf(root);
}
int SmallestDepth(){
return SmallestDepth(root);
}
int IsCompletBiTree(){
return IsCompleteBiTree(root);
}
int IsStructureSymmetric(){
return IsStructureSymmetric(root);
}
int IsL_R_Check(){
return IsL_R_Check(root->lchild, root->rchild);
}
//根据前序和中序序列构造二叉树 有参构造函数
BiTree(ElemType *preOrder, ElemType *inOrder, int len) {
root = Rebuild(preOrder, inOrder, len);
}
BiNode<ElemType>* Rebuild(ElemType *preOrder,ElemType *inOrder,int n);
//二叉树第k层的结点个数和叶子结点个数
int GetNodesNumberOfKthLevle(int k){
return GetNodesNumberOfKthLevle(root, k);
};
int GetLeafNodesNumberOfKthLevel(int k){
return GetLeafNodesNumberOfKthLevel(root, k);
};
//打印二叉树第k层的结点和叶子结点
void PrintNodesOfKthLevel(int k){
PrintNodesOfKthLevel(root, k);
};
void PrintLeafNodesOfKthLevel(int k){
PrintLeafNodesOfKthLevel(root, k);
};
};
#endif /* BiTree_hpp */
.m文件,因为我的不能设置成.m文件,只好用另一个cpp文件来代替了
#include "BiTree.hpp"
#include "CirQueue.cpp"
#include <iostream>
using namespace std;
//前序遍历
template <class Elemtype>
void BiTree<Elemtype>::PreOrder(BiNode<Elemtype> *bt){
if (bt == NULL) {
return;
}
else{
cout << bt->data << " ";
PreOrder(bt->lchild);
PreOrder(bt->rchild);
}
}
//中序遍历
template <class Elemtype>
void BiTree<Elemtype>::InOrder(BiNode<Elemtype> *bt){
if(bt==NULL){
return;
}
else{
InOrder(bt->lchild);
cout << bt->data << " ";
InOrder(bt->rchild);
}
}
//后序遍历
template <class ElemType>
void BiTree<ElemType>::PostOrder(BiNode<ElemType> *bt){
if (bt == NULL) {
return;
}
else{
PostOrder(bt->lchild);
PostOrder(bt->rchild);
cout << bt->data << "";
}
}
//层序遍历
template <class ElemType>
void BiTree<ElemType>::LevelOrder(BiNode<ElemType> *bt){
const int MaxSize = 100;
//采用顺序队列,假设不会发生溢出
int front = 0, rear = 0;
BiNode<ElemType> *Q[MaxSize],*q;
if (bt == NULL) {
return;
}
else{
Q[rear++] = bt; //bt入队
//队列非空时循环
while (front!=rear) {
q = Q[front++]; //队头出队
cout << q->data << " "; //访问队头
if (q->lchild != NULL) { //如果队头有左孩子,则左孩子入队
Q[rear++] = q->lchild;
}
if (q->rchild !=NULL) { //如果队头有右孩子,则右孩子入队
Q[rear++] = q->rchild;
}
}
}
}
//构造函数
template <class ElemType>
BiNode<ElemType> *BiTree<ElemType>::Creat(BiNode<ElemType> *bt){
ElemType ch;
// cout << "请输入创建一棵二叉树的节点数据:" << endl;
cin >> ch;
if (ch == '*'){
return NULL;
}
else{
bt = new BiNode<ElemType>;
bt->data = ch;
bt->lchild = Creat(bt->lchild);
bt->rchild = Creat(bt->rchild);
}
return bt;
}
//析构函数
template <class ElemType>
void BiTree<ElemType>::Release(BiNode<ElemType> *bt){
if (bt != NULL) {
Release(bt->lchild);
Release(bt->rchild);
delete bt;
}
}
//求二叉树的深度
template <class ElemType>
int BiTree<ElemType>::Depth(BiNode<ElemType> *bt){
if (bt == NULL) {
return 0;
}
else{
int dep1 = Depth(bt->lchild);
int dep2 = Depth(bt->rchild);
return (dep1>dep2)?(dep1+1):(dep2+1);
}
}
//求二叉树的节点个数
int countNode = 0;
template <class ElemType>
int BiTree<ElemType>::Count(BiNode<ElemType> *bt){
if (bt != NULL) {
Count(bt->lchild);
countNode++;
Count(bt->rchild);
}
return countNode;
}
//求二叉树的叶子节点个数
int countLeaf = 0;
template <class ElemType>
int BiTree<ElemType>::CountLeaf(BiNode<ElemType> *bt){
if (bt != NULL) {
if (bt->lchild == NULL && bt->rchild == NULL) {
countLeaf++;
}
CountLeaf(bt->lchild);
CountLeaf(bt->rchild);
}
return countLeaf;
}
//输出二叉树的叶子结点
template<class ElemType>
void BiTree<ElemType>::PrintLeaf(BiNode<ElemType> *bt){
if(bt != NULL){
if (bt->lchild == NULL && bt->rchild == NULL) {
cout << bt->data << " " ;
}
PrintLeaf(bt->lchild);
PrintLeaf(bt->rchild);
}
}
//求二叉树的最小深度
template <class ElemType>
int BiTree<ElemType>::SmallestDepth(BiNode<ElemType> *bt){
if(bt == NULL)
return 0;
if(bt->lchild == NULL)
return SmallestDepth(bt->rchild) + 1;
if(bt->rchild == NULL)
return SmallestDepth(bt->lchild) + 1;
int m = SmallestDepth(bt->lchild) + 1;
int n = SmallestDepth(bt->rchild) + 1;
return m < n ? m:n;
}
//判断二叉树是否为完全二叉树
template <class ElemType>
int BiTree<ElemType>::IsCompleteBiTree(BiNode<ElemType> *bt){
CirQueue<BiNode<ElemType> *> Q;
BiNode<ElemType> *p;
if(bt == NULL) return 1;
Q.EnQueue(bt);
//当出队的队头指针不为空时,将其左、右指针入队
while ( (p = Q.DeQueue()) != NULL) {
Q.EnQueue(p->lchild);
Q.EnQueue(p->rchild);
}
//当遇到空指针时,判断队列中是否有非空指针
//如果有,则不是完全二叉树,没有,则为完全二叉树
while(!Q.Empty()){
p = Q.DeQueue();
if (p != NULL){
return 0;
}
}
return 1;
}
//判断二叉树左右子树是否结构对称
template <class ElemType>
int BiTree<ElemType>::IsCheck(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild){
if(lchild == NULL && rchild == NULL){
return 1;
}
if(lchild == NULL || rchild == NULL){
return 0;
}
return IsCheck(lchild->lchild, rchild->rchild) && IsCheck(lchild->rchild, rchild->lchild);
}
//判断二叉树是否结构对称
template <class ElemType>
int BiTree<ElemType>::IsStructureSymmetric(BiNode<ElemType> *bt){
if(bt == NULL){
return 1;
}
return IsCheck(bt->lchild,bt->rchild);
}
//判断二叉树是否对称
template <class ElemType>
int BiTree<ElemType>::IsL_R_Check(BiNode<ElemType> *lchild, BiNode<ElemType> *rchild){
if(lchild == NULL && rchild == NULL){
return 1;
}
if(lchild == NULL || rchild == NULL){
return 0;
}
//此处与判断结构性对称不同
if (lchild->data != rchild->data) {
return 0;
}
return IsL_R_Check(lchild->lchild, rchild->rchild) && IsL_R_Check(lchild->rchild, rchild->lchild);
}
/*根据前序遍历和中序遍历重建二叉树*/
template <class ElemType>
BiNode<ElemType> * BiTree<ElemType>::Rebuild(ElemType *preOrder, ElemType *inOrder, int n){
if (n == 0) {
return NULL;
}
//获得前序遍历的第一个节点
ElemType c = preOrder[0];
//创建根节点
BiNode<ElemType> *node = new BiNode<ElemType>;
node->data = c;
node->lchild = NULL;
node->rchild = NULL;
int i;
//在中序遍历序列中寻找根节点的位置
for (i = 0; i < n && inOrder[i] != c; i++) {
}
//左子树节点的个数
int lenLeft = i;
//右子树节点个数
int lenRight = n - i - 1;
//左子树不为空,递归重建左子树
if (lenLeft > 0) {
node->lchild = Rebuild(&preOrder[1], &inOrder[0], lenLeft);
}
//右子树不为空,递归重建右子树
if (lenRight > 0) {
node->rchild = Rebuild(&preOrder[lenLeft+1],&inOrder[lenLeft+1],lenRight);
}
return node;
}
//二叉树第k层的结点个数和叶子结点个数
template <class ElemType>
int BiTree<ElemType>::GetNodesNumberOfKthLevle(BiNode<ElemType> *bt, int k){
if (bt == NULL || k < 1) {
return 0;
}
if (k == 1) {
return 1;
}
return GetNodesNumberOfKthLevle(bt->lchild, k - 1) + GetNodesNumberOfKthLevle(bt->rchild, k-1);
}
template <class ElemType>
int BiTree<ElemType>::GetLeafNodesNumberOfKthLevel(BiNode<ElemType> *bt, int k){
if (bt == NULL || k < 1) {
return 0;
}
else {
if (k == 1) {
if (bt->lchild == NULL && bt->rchild == NULL) return 1;
else return 0;
}
else if(k > 1){
return GetLeafNodesNumberOfKthLevel(bt->lchild, k-1) + GetLeafNodesNumberOfKthLevel(bt->rchild, k-1);
}
}
return 1;
}
//打印二叉树第k层的结点和叶子结点
template <class ElemType>
void BiTree<ElemType>::PrintNodesOfKthLevel(BiNode<ElemType> *bt, int k){
if (bt == NULL || k < 1) {
return;
}
if(k == 1){
cout << bt->data<<" ";
}
PrintNodesOfKthLevel(bt->lchild, k - 1);
PrintNodesOfKthLevel(bt->rchild, k - 1);
}
template <class ElemType>
void BiTree<ElemType>::PrintLeafNodesOfKthLevel(BiNode<ElemType> *bt, int k){
if (bt == NULL || k < 1) return ;
if (bt != NULL ){
if (k == 1){
if(bt->lchild == NULL && bt->rchild == NULL)
cout << bt->data<< " ";}
else if (k > 1){
PrintLeafNodesOfKthLevel(bt->lchild, k-1);
PrintLeafNodesOfKthLevel(bt->rchild, k-1);
}
}
}
队列的类模版(部分):
#ifndef CIRQUEUE_H
#define CIRQUEUE_H
const int QueueSize = 100; /*定义循环队列的容量*/
template <class ElemType> /*定义模板类CirQueue*/
class CirQueue{
public:
CirQueue(); /*构造函数,循环队列的初始化*/
void EnQueue(ElemType x); /*入队操作*/
ElemType DeQueue(); /*出队操作*/
int Empty(); /*判断队列是否为空,若为空返回1,否则返回0*/
private:
ElemType data[QueueSize]; /*存放队列元素的数组*/
int front, rear; /*队头,队尾指针*/
};
#endif
.cpp(.m)文件
#include <iostream>
using namespace std;
#include "CirQueue.hpp"
template <class ElemType>
CirQueue<ElemType>::CirQueue() {
front = QueueSize-1;
rear = QueueSize-1;
}
template <class ElemType>
void CirQueue<ElemType>::EnQueue(ElemType x) {
if((rear + 1) % QueueSize == front)
throw "循环队列已满,溢出!";
rear = (rear + 1) % QueueSize;
data[rear] = x;
}
template <class ElemType>
ElemType CirQueue<ElemType>::DeQueue() {
if(rear == front)
throw "循环队列为空!";
front = (front + 1) % QueueSize;
return data[front];
}
template <class ElemType>
int CirQueue<ElemType>::Empty() {
if(front == rear)
return 1;
else
return 0;
}