//初始化队列
void InitStatus (Status *Sta)
{
assert (Sta != NULL);
Sta->rear = 0;
Sta->front = 0;
}
//入队列
void PushStatus (Status *sta, pBTNode data)
{
assert (sta);
if (sta->rear == MAX_SIZE)
{
printf ("队列已满,无法入队列!!!\n");
return;
}
sta->data[sta->rear] = data;
sta->rear++;
}
//出队列,返回对头元素
pBTNode PopStatus(Status *sta)
{
int i = 0;
pBTNode ch;
assert (sta != NULL);
if (sta->rear == 0)
{
printf ("队列为空!!!\n");
return NULL;
}
ch = sta->data[0];
for (i = 0; irear-1; ++i)
{
sta->data[i] = sta->data[i+1];
}
sta->rear --;
return ch;
}
//判断队列是否为空
int IsEmpty_Status (Status *sta)
{
return sta->rear==0;
}
void InitStack (Stack *p) //初始化
{
assert (p != NULL);
p->top = 0;
}
void PushStack (Stack *p, pBTNode d) //入栈
{
assert (p);
if (p->top == MAXSIZE)
{
printf ("栈满,无法入栈!!!\n");
return;
}
p->data[p->top++] = d;
}
void PopStack (Stack *p)//出栈
{
assert (p);
if (p->top == 0)
{
printf ("栈空,操作失败!!!\n");
return;
}
p->top --;
}
int IsStaticEmpty (Stack *p) // 判空
{
return (p->top == 0);//如果为空,返回1;如果不为空,返回0
}
pBTNode TopNumAndTop (Stack *p) //返回栈顶元素(出栈)
{
if (p->top == 0)
{
printf ("栈为空!!\n");
return 0;
}
return p->data[--(p->top)];
}
pBTNode TopNum (Stack *p) //返回栈顶元素(不出栈)
{
if (p->top == 0)
{
printf ("栈为空!!\n");
return 0;
}
return p->data[(p->top)-1];
}
pBTNode BuyNode (DataType d)
{
pBTNode node = (pBTNode) malloc (sizeof (BTNode));
if (NULL == node)
{
perror ("BuyNode :: malloc>>");
return NULL;
}
node->d = d;
node->_pLeft = NULL;
node->_pRight = NULL;
return node;
}
void Create_Tree(BTNode **pRoot, DataType* arr, int len, int* count)
{
assert (pRoot);
assert (arr);
if (*count < len && arr[*count] != '#')
{
(*pRoot) = BuyNode (arr[*count]); //创建根节点
(*count)++;
Create_Tree(&(*pRoot)->_pLeft, arr, len, count); //创建左子树
(*count)++;
Create_Tree(&(*pRoot)->_pRight, arr, len, count); //创建右子树
}
}
//前序(递归):根节点 --> 左子树 --> 右子树
void PreOrder (BTNode *pRoot)
{
if (pRoot != NULL)
{
// 遍历更节点
printf ("%c ", pRoot->d);
//左子树
PreOrder (pRoot->_pLeft);
//右子树
PreOrder (pRoot->_pRight);
}
}
//先遍历根节点,如果根节点的左子树不为空,在遍历左子树的更节点,如果根节点的右子树不为空,右子树更节点入栈
//当左子树为空时,栈顶元素出栈,在以栈顶元素作为根节点
//直到栈为空
void PreOrderNoR(BTNode* pRoot) //前序遍历(非递归)
{
BTNode* cur = NULL;
Stack s;
if (pRoot == NULL)
{
printf ("树为空!!!\n");
return;
}
//树不为空
InitStack(&s);
printf ("%c ", pRoot->d);
cur = pRoot->_pLeft;
if (pRoot->_pRight != NULL)
{
PushStack(&s, pRoot->_pRight);
}
while (!IsStaticEmpty(&s) || cur != NULL)
{
while (cur != NULL)
{
if (cur->_pRight != NULL)
{
PushStack(&s, cur->_pRight);
}
printf ("%c ", cur->d);
cur = cur->_pLeft;
}
if (!IsStaticEmpty(&s))
cur = TopNumAndTop(&s);
}
}
//中序(递归):左子树--> 根节点--> 右子树
void InOrder (BTNode *pRoot)
{
if (pRoot != NULL)
{
InOrder (pRoot->_pLeft);
printf ("%c ", pRoot->d);
InOrder (pRoot->_pRight);
}
}
//中序非递归遍历
//先找到最左边的节点
void InOrderNor(BTNode* pRoot)
{
BTNode* cur = NULL;
Stack s;
if (pRoot == NULL)
{
printf ("树为空!!!\n");
return ;
}
//树不为空
InitStack(&s);
cur = pRoot;
while (!IsStaticEmpty(&s) || cur)
{
while (cur)
{
PushStack(&s, cur);
cur = cur->_pLeft;
}
cur = TopNumAndTop(&s);
printf ("%c ", cur->d);
cur = cur->_pRight;
}
}
//后序(递归): 左子树--> 右子树 --> 根节点
void PostOrder (BTNode *pRoot) //后序遍历(递归)
{
if (pRoot != NULL)
{
PostOrder (pRoot->_pLeft);
PostOrder (pRoot->_pRight);
printf ("%c ", pRoot->d);
}
}
void PostOrderNoR (BTNode *pRoot) //后序遍历(非递归)
{
Stack s;
BTNode* cur = NULL;
BTNode* mask = NULL;// 用来标记已经遍历过得节点
if (pRoot == NULL)
{
printf ("树为空!!!\n");
return;
}
InitStack(&s);
cur = pRoot;
//树不为空
while (!IsStaticEmpty(&s) || cur)
{
BTNode* top = NULL;
while (cur) //找最左边的节点
{
PushStack(&s, cur);
cur = cur->_pLeft;
}
top = TopNum(&s);
//如果cur的右孩子为空或者已经被遍历过,则遍历该节点
if (top->_pRight == NULL || top->_pRight->d == mask->d)
{
printf ("%c ", top->d);
mask = top; //刷新标记
PopStack(&s); //栈顶元素出栈
}
else //如果右孩子不为空并且右孩子没有被遍历过,找右子树最左边的节点
{
cur = top->_pRight;
// mask = cur->_pRight;
}
}
}
void FloorOrder (BTNode *pRoot)
{
Status sta;
pBTNode proot;
InitStatus (&sta);
assert (pRoot != NULL);
PushStatus (&sta, pRoot);//根节点入队列
while (!IsEmpty_Status(&sta))
{
proot = PopStatus (&sta);
printf ("%c ", proot->d);
if (proot->_pLeft != NULL)
{
PushStatus (&sta, proot->_pLeft);
}
if (proot->_pRight != NULL)
{
PushStatus (&sta, proot->_pRight);
}
}
}
int Max (int a, int b)
{
return a>b?a:b;
}
int GetHeight (BTNode *pRoot)
{
if (pRoot == NULL)
{
return 0;
}
else if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
{
return 1;
}
else
{
return 1+ (Max (GetHeight (pRoot->_pLeft), GetHeight(pRoot->_pRight)));
}
}
int GetLeaf (BTNode *pRoot)
{
if (NULL == pRoot)
{
return 0;
}
else if (pRoot->_pLeft == NULL && pRoot->_pRight == NULL)
{
return 1;
}
else
{
return GetLeaf(pRoot->_pLeft)+GetLeaf(pRoot->_pRight);
}
}
int GetNode (BTNode *pRoot) //求二叉树节点的个数
{
if (NULL == pRoot)
{
return 0;
}
else if ( NULL == pRoot->_pLeft && NULL == pRoot->_pRight )
{
return 1;
}
else
{
return GetNode (pRoot->_pLeft)+GetNode (pRoot->_pRight)+1;
}
}
int GetKNode (BTNode* pRoot, int k, int high)
{
if (k <= 0 || k > high || pRoot == NULL) //如果k小于等于零,或者k大于树的高度,或者树为空
return 0;
else if (k == 1)
{
return 1;
}
else
{
return (GetKNode (pRoot->_pLeft , k-1, high) + GetKNode (pRoot->_pRight, k-1, high));
}
}
pBTNode GetParent(BTNode* pRoot, DataType data) //求一个节点的双亲结点
{
BTNode *root = pRoot;
assert (pRoot != NULL);
if (root->d == data)
{
return NULL;
}
if (pRoot->_pLeft != NULL || pRoot->_pRight != NULL)
{
if (pRoot->_pLeft->d == data || pRoot->_pRight->d == data)
return pRoot;
else
{
return GetParent (pRoot->_pLeft, data);
return GetParent (pRoot->_pRight, data);
}
}
return NULL;
}
//递归求一个节点的左孩子
pBTNode LeftNode(pBTNode cur, DataType data)
{
BTNode *ret = NULL;
if(NULL == cur)
return NULL;
if(cur->d == data && cur->_pLeft != NULL)
{
return cur->_pLeft;
}
ret = LeftNode(cur->_pLeft, data);
if(NULL == ret)
{
ret = LeftNode(cur->_pRight, data);
}
return ret;
}
pBTNode GetLeftChild (BTNode* pRoot, DataType data) //获取一个节点的左孩子结点
{
BTNode *cur = NULL;
Status sta; //队列
InitStatus (&sta);
assert (pRoot != NULL);
cur = pRoot;
PushStatus (&sta, cur);//头节点入队列
while (!IsEmpty_Status (&sta) && cur)
{
cur = PopStatus (&sta);
if (cur->d == data)
{
return cur->_pLeft;
}
if (cur->_pLeft != NULL)//若左子树不为空,左子树头节点入队列
{
PushStatus (&sta, cur->_pLeft);
}
if (cur->_pRight != NULL)//若右子树不为空,右子树头节点入队列
{
PushStatus (&sta, cur->_pRight);
}
}
return NULL;
}
pBTNode GetRightChild (BTNode* pRoot, DataType data) //获取一个节点的右孩子结点
{
BTNode *cur = NULL;
Status sta; //队列
InitStatus (&sta);
assert (pRoot != NULL);
cur = pRoot;
PushStatus (&sta, cur);//头节点入队列
while (!IsEmpty_Status (&sta) && cur)
{
cur = PopStatus (&sta);
if (cur->d == data)
{
return cur->_pRight;
}
if (cur->_pLeft != NULL)//若左子树不为空,左子树头节点入队列
{
PushStatus (&sta, cur->_pLeft);
}
if (cur->_pRight != NULL)//若右子树不为空,右子树头节点入队列
{
PushStatus (&sta, cur->_pRight);
}
}
return NULL;
}
void swap (BTNode **a, BTNode **b)
{
BTNode * tmp = *a;
*a = *b;
*b = tmp;
}
void BTreeMirrorR(BTNode *pRoot)// 求二叉树的镜像(递归)
{
if (pRoot != NULL)
{
if (pRoot->_pLeft != NULL || pRoot->_pRight != NULL)
{
swap (&pRoot->_pLeft, &pRoot->_pRight);
BTreeMirrorR(pRoot->_pLeft);
BTreeMirrorR(pRoot->_pRight);
}
}
}
void BTreeMirrorNoR(BTNode *pRoot)// 求二叉树的镜像(非递归)
{
Status s;
BTNode* cur = NULL;
InitStatus(&s);
if (pRoot == NULL)
{
return NULL;
}
PushStatus (&s, pRoot); //头结点入队列
while ( !IsEmpty_Status (&s))
{
cur = PopStatus(&s); //对头元素出队列并返回对头元素
if (cur ->_pLeft != NULL )
{
PushStatus (&s, cur->_pLeft); //左孩子不为空,左孩子入队列
}
if (cur->_pRight != NULL)
{
PushStatus(&s, cur->_pRight); //右孩子不为空,右孩子入队列
}
swap (&cur->_pLeft, &cur->_pRight);
}
}
头文件 包含以下内容 (BTree.h)
#ifndef __BTREE_H__
#define __BTREE_H__
#include
#include
#include
#include
#define MAX_SIZE 10 //队列
#define MAXSIZE 30 //栈
typedef char DataType;
/////////////////////////////////////////////////////////////////////////////////////////////
//二叉树
typedef struct BTNode
{
struct BTNode* _pLeft;
struct BTNode* _pRight;
DataType d;
}BTNode, *pBTNode;
////////////////////////////////////////////////////////////////////////////////////////////
//队列
typedef struct Status
{
int front;//对头
int rear;//对尾
pBTNode data[MAX_SIZE];
}Status;
//////////////////////////////////////////////////////////////////////////////////////////////
//栈
typedef struct STACK
{
int top ; //栈顶
pBTNode data[MAXSIZE]; //数据
}Stack;
////////////////////////////////////////////////////////////////////////////////////////////
//队列操作
void InitStatus (Status *Sta);//初始化
void PushStatus (Status *sta, pBTNode data);//入队列
int IsEmpty_Status (Status *sta);//判断队列是否为空
pBTNode PopStatus(Status *sta); //出队列,返回对头元素
//////////////////////////////////////////////////////////////////////////////////////////////
//栈操作
void InitStack (Stack *p); //初始化
void PushStack (Stack *p, pBTNode d); //入栈
void PopStack (Stack *p); // 出栈
int IsStaticEmpty (Stack *p); // 判空
pBTNode TopNumAndTop (Stack *p); //返回栈顶元素并出栈
pBTNode TopNum (Stack *p); //返回栈顶元素不出栈
/////////////////////////////////////////////////////////////////////////////////////////////////
//二叉树操作
pBTNode BuyNode (DataType d); //创建新节点
void Create_Tree(BTNode **pRoot, DataType* arr, int len, int* count); //创建树
void PreOrder (BTNode *pRoot); //前序遍历(递归)
void PreOrderNoR(BTNode* pRoot); //前序遍历(非递归)
void InOrder (BTNode *pRoot); //中序遍历(递归)
void InOrderNor(BTNode* pRoot); //中序遍历(非递归)
void PostOrder (BTNode *pRoot); //后序遍历(递归)
void PostOrderNoR (BTNode *pRoot); //后序遍历(非递归) //后序遍历(非递归)
void FloorOrder (BTNode *pRoot);//层序遍历
int GetHeight (BTNode *pRoot); //求树的高度
int GetLeaf (BTNode *pRoot); //求叶子节点的个数
int GetNode (BTNode *pRoot); //求二叉树节点的个数
int GetKNode (BTNode* pRoot, int k, int high); //求第k层的节点个数
pBTNode GetParent(BTNode* pRoot, DataType node); //求一个节点的双亲结点
pBTNode GetLeftChild (BTNode* pRoot, DataType node); //获取一个节点的左孩子结点
pBTNode LeftNode(pBTNode cur, DataType data); //求一个节点的左孩子节点
pBTNode GetRightChild (BTNode* pRoot, DataType data); //获取一个节点的右孩子结点
void BTreeMirrorR(BTNode *Root); // 求二叉树的镜像(递归)
void BTreeMirrorNoR(BTNode *Root); // 求二叉树的镜像(非递归)
#endif
测试代码如下test.c:
#include "BTree.h"
void test_BTree()
{
pBTNode pRoot = NULL;
pBTNode ret = NULL;
char arr[] = {"ABD###CE##F"};
int index = 0;
Create_Tree (&pRoot, arr, strlen(arr), &index);
printf ("前序遍历(递归):\n");
PreOrder (pRoot);
printf ("\n");
printf ("前序遍历(非递归):\n");
PreOrderNoR (pRoot);
printf ("\n");
printf ("中序遍历(递归):\n");
InOrder (pRoot);
printf ("\n");
printf ("中序遍历(非递归):\n");
InOrderNor (pRoot);
printf ("\n");
printf ("后序遍历(递归):\n");
PostOrder (pRoot);
printf ("\n");
printf ("后序遍历(非递归):\n");
PostOrderNoR (pRoot);
printf ("\n");
printf ("层序遍历:\n");
FloorOrder(pRoot);
printf ("\n");
printf ("树的高度为:%d\n", GetHeight(pRoot));
printf ("叶子节点的个数为:%d\n", GetLeaf (pRoot));
printf ("二叉树节点的个数为:%d\n", GetNode (pRoot));
printf ("二叉树第2层节点个数为:%d\n", GetKNode (pRoot, 2, GetHeight(pRoot)));
ret = GetParent (pRoot, 'B');
if (ret != NULL)
{
printf ("B的双亲结点为:%c\n", ret->d);
}
ret = LeftNode(pRoot, 'C');
if (ret != NULL)
{
printf ("C的左孩子为:%c\n", ret->d);
}
ret = GetRightChild (pRoot, 'A');
if (ret != NULL)
{
printf ("A的右孩子为:%c\n", ret->d);
}
printf ("递归求二叉树的镜像:\n");
BTreeMirrorR(pRoot);
InOrder (pRoot);
printf ("\n");
printf ("非递归求二叉树的镜像:\n");
BTreeMirrorNoR(pRoot);
InOrder (pRoot);
printf ("\n");
}
void test_Status()
{
Status Sta;
InitStatus (&Sta);
}
int main ()
{
test_BTree();
test_Status();
system ("pause");
return 0;
}
测试结果: