bittree.h 文件
#ifndef _BIT_TREE_H_
#define _BIT_TREE_H_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
//树的定义是递归定义的,节点下面又拆分为左子树和右子树
//树是由节点组成,除了叶子节点,其他节点又是相对的根节点,
//相对的根节点下有相对的左右子树
//树的遍历的本质就是走一圈,每一个非叶子节点就是相对的根节点,都经过3次
//第一次访问为先序,第二次访问为中序,第三次访问为后序
#ifndef bool
#define bool int
#define true 1
#define false 0
#endif
//数的头首地址就可以用第一个节点的地址表示
typedef struct BitNode
{
int data;
struct BitNode *lchild,*rchild;
}BitNode,*BitTree;
#ifdef __cplusplus
extern "C"{
#endif
extern void preOrder(BitNode* root);
extern void midOrder(BitNode* root);
extern void lastOrder(BitNode* root);
extern void countLeafNodes(BitNode* root,int* sum);
extern int getDepth(BitNode* root);
extern BitNode* copyBitTree(BitNode* root);
#ifdef __cplusplus
}
#endif
#endif
bittree.c 文件
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "bittree.h"
//树的先序遍历。递归算法。
void preOrder(BitNode* root)
{
if (root == NULL)
{
return;
}
//打印根节点的数据
printf("先序遍历:%d \n",root->data);
//遍历左子树
if (root->lchild != NULL)
{
preOrder(root->lchild);
}
//遍历右子数
if (root->rchild != NULL)
{
preOrder(root->rchild);
}
}
//树的中序遍历。递归算法
void midOrder(BitNode* root)
{
if (root == NULL)
{
return;
}
//遍历左子树
if (root->lchild != NULL)
{
midOrder(root->lchild);
}
//打印根节点的数据
printf("中序遍历:%d \n",root->data);
//遍历右子数
if (root->rchild != NULL)
{
midOrder(root->rchild);
}
}
//树的后序遍历。递归算法
void lastOrder(BitNode* root)
{
if (root == NULL)
{
return;
}
//遍历左子树
if (root->lchild != NULL)
{
lastOrder(root->lchild);
}
//遍历右子数
if (root->rchild != NULL)
{
lastOrder(root->rchild);
}
//打印根节点的数据
printf("后序遍历:%d \n",root->data);
}
//统计叶子节点的个数,叶子节点就是没有孩子的节点。递归算法
void countLeafNodes(BitNode* root,int* sum)
{
if (root)
{
//先统计传入节点有没有叶子节点
if (root->lchild == NULL && root->rchild == NULL)
{
(*sum) = (*sum) + 1;
}
//统计传入节点左子树的叶子节点,存在左子树
if (root->lchild)
{
countLeafNodes(root->lchild,sum);
}
//统计传入节点右子树的叶子节点,存在右子树
if (root->rchild)
{
countLeafNodes(root->rchild,sum);
}
}
}
//求树的深度,递归算法
int getDepth(BitNode* root)
{
int leftdepth ;
int rightdepth ;
int depth ;
if (root == NULL)
{
return 0;
}
else
{
leftdepth = getDepth(root->lchild); //左子树的深度
rightdepth = getDepth(root->rchild); //右子树的深度
depth = 1 + (leftdepth > rightdepth ? leftdepth : rightdepth); //左右子树最大深度加1(根节点)
}
return depth;
}
//copy树,递归
BitNode* copyBitTree(BitNode* root)
{
BitNode* newNode = NULL;
BitNode* newLeftChild = NULL;
BitNode* newRightChild = NULL;
if (root == NULL)
{
return NULL;
}
//copy左子树
if (root->lchild != NULL)
{
newLeftChild = copyBitTree(root->lchild);
}
else newLeftChild = NULL;
//copy右子树
if (root->rchild != NULL)
{
newRightChild = copyBitTree(root->rchild);
}
else newRightChild = NULL;
//为copy的节点分配内存
newNode = (BitNode*)malloc(sizeof(BitNode));
if (newNode == NULL)
{
return NULL;
}
//为copy的节点指针域赋值
newNode->lchild = newLeftChild;
newNode->rchild = newRightChild;
//为copy的数据域赋值
newNode->data = root->data;
return newNode;
}
/***********************测试代码********************/
/*
void main()
{
//BitNode t1;
//memset(&t1,0,sizeof(BitNode));
BitNode *t1,*t2,*t3,*t4,*t5;
int sumleafnode = 0;
int depth = 0;
t1 = NULL;t2 = NULL; t3 = NULL; t4 = NULL; t5 = NULL;
t1 = (BitNode *)malloc(sizeof(BitNode));
t2 = (BitNode *)malloc(sizeof(BitNode));
t3 = (BitNode *)malloc(sizeof(BitNode));
t4 = (BitNode *)malloc(sizeof(BitNode));
t5 = (BitNode *)malloc(sizeof(BitNode));
memset(t1,0,sizeof(BitNode));
memset(t2,0,sizeof(BitNode));
memset(t3,0,sizeof(BitNode));
memset(t4,0,sizeof(BitNode));
memset(t5,0,sizeof(BitNode));
t1->data = 1;
t2->data = 2;
t3->data = 3;
t4->data = 4;
t5->data = 5;
t1->lchild = t2;
t1->rchild = t3;
t2->lchild = t4;
t3->lchild = t5;
preOrder(t1);
midOrder(t1);
lastOrder(t1);
countLeafNodes(t1,&sumleafnode);
printf("叶子的节点个数是:%d \n",sumleafnode);
depth = getDepth(t1);
printf("树的深度是:%d \n",depth);
{
BitNode* copytree = copyBitTree(t1);
preOrder(copytree);
}
if (t1 != NULL)
{
free(t1);
t1 = NULL;
}
if (t2 != NULL)
{
free(t2);
t2 = NULL;
}
if (t3 != NULL)
{
free(t3);
t3 = NULL;
}
if (t4 != NULL)
{
free(t4);
t4 = NULL;
}
if (t5 != NULL)
{
free(t5);
t5 = NULL;
}
system("pause");
}
*/
#include <iostream>
#include <stack>
#include "bittree.h"
using namespace std;
/********二叉树的中序非递归遍历,采用栈的方式*****************/
/*
步骤1:如果结点没有左子树,该结点入栈;
如果结点没有左子树,访问该结点;
步骤2:如果结点有右子树,重复步骤1;
如果结点没有右子树(结点访问完毕),
根据栈顶指示回退,访问栈顶元素,
并访问右子树,重复步骤1;如果栈为空,表示遍历完毕。
注意:入栈的结点表示,本身没有被访问过,同时右子树也没有被访问过。
*/
//一直往左走,找到中序遍历的起点
BitNode* goleft(BitNode* root, stack<BitNode*>& s)
{
if (root == NULL)
{
return NULL;
}
//如果该结点有左子树,该结点入栈,指针下移
while(root->lchild != NULL)
{
s.push(root);
root = root->lchild;
}
//如果没有左子树,返回该结点
return root;
}
void stlmidOrder(BitNode* root)
{
BitNode* t = NULL;
stack<BitNode*> s;
t = goleft(root,s);
while(t)
{
printf("中序非递归遍历:%d \n",t->data);
//如果t有右子树,重复步骤1
if (t->rchild != NULL)
{
t = goleft(t->rchild,s);//右子树中中序遍历起点
}
else if(!s.empty()) //如果t没有右子树,根据栈顶指示回退
{
t = s.top();
s.pop();
}
else //如果t没有右子树,并且栈为空
{
t = NULL;
}
}
}
void main()
{
BitNode *t1,*t2,*t3,*t4,*t5;
int sumleafnode = 0;
int depth = 0;
t1 = NULL;t2 = NULL; t3 = NULL; t4 = NULL; t5 = NULL;
t1 = (BitNode *)malloc(sizeof(BitNode));
t2 = (BitNode *)malloc(sizeof(BitNode));
t3 = (BitNode *)malloc(sizeof(BitNode));
t4 = (BitNode *)malloc(sizeof(BitNode));
t5 = (BitNode *)malloc(sizeof(BitNode));
memset(t1,0,sizeof(BitNode));
memset(t2,0,sizeof(BitNode));
memset(t3,0,sizeof(BitNode));
memset(t4,0,sizeof(BitNode));
memset(t5,0,sizeof(BitNode));
t1->data = 1;
t2->data = 2;
t3->data = 3;
t4->data = 4;
t5->data = 5;
t1->lchild = t2;
t1->rchild = t3;
t2->lchild = t4;
t3->lchild = t5;
//preOrder(t1);
midOrder(t1);
stlmidOrder(t1);
//lastOrder(t1);
countLeafNodes(t1,&sumleafnode);
printf("叶子的节点个数是:%d \n",sumleafnode);
depth = getDepth(t1);
printf("树的深度是:%d \n",depth);
{
BitNode* copytree = copyBitTree(t1);
preOrder(copytree);
}
if (t1 != NULL)
{
free(t1);
t1 = NULL;
}
if (t2 != NULL)
{
free(t2);
t2 = NULL;
}
if (t3 != NULL)
{
free(t3);
t3 = NULL;
}
if (t4 != NULL)
{
free(t4);
t4 = NULL;
}
if (t5 != NULL)
{
free(t5);
t5 = NULL;
}
system("pause");
}
可能会调用其它头文件或源文件,如果调用,请翻看我的其它博客,对其头文件或源文件的实现方式。
good luck !