//.h
#ifndef _BINARYTREE_
#define _BINARYTREE_
#include"stdio.h"
#include"malloc.h"
typedef char datatype;
const int Maxsize = 1000;
typedef struct node
{
datatype data;
struct node* left;
struct node* right;
}Node, *pTree;
typedef pTree ElementType;
pTree create()
{
pTree t;
datatype ch;
//printf("Enter: ");
ch = getchar();
if (ch == '?')
{
t = NULL;
return t;
}
else
{
t = (pTree)malloc(sizeof(Node));
t->data = ch;
//t->left = NULL;
//t->right = NULL;
t->left = create();
t->right = create();
}
return t;
}
void preorder(pTree t)
{
if (t)
{
printf("%c", t->data);
preorder(t->left);
preorder(t->right);
}
//printf("\n");
}
void inorder(pTree t)
{
if (t)
{
inorder(t->left);
printf("%c", t->data);
inorder(t->right);
}
//printf("\n");
}
void postorder(pTree t)
{
if (t)
{
postorder(t->left);
postorder(t->right);
printf("%c", t->data);
}
//printf("\n");
}
static int jcount = 0;
static int ycount = 0;
static int dcount = 0;
int NodeCount(pTree t)
{
if (t)
{
jcount++;
if (!t->left && !t->right)
ycount++;
NodeCount(t->left);
NodeCount(t->right);
}
return ycount;
}
int depth(pTree t)
{
int deep = 0;
if (t)
{
int ldepth = depth(t->left);
int rdepth = depth(t->right);
deep = (ldepth >= rdepth ? ldepth + 1 : rdepth + 1);
}
return deep;
}
//------------------------------------创建栈-----------------------
//typedef pTree ElementType
typedef struct
{
ElementType Data[Maxsize];
int top;
}stack,*pStack;
stack* creat_stack()
{
stack* s = (stack*)malloc(sizeof(stack));
s->top = -1;
return s;
}
//进栈
void Push(stack* pTrs, ElementType item)
{
if (pTrs->top == Maxsize - 1)//判断栈是否满
{
printf("堆栈满");
//return;
}
else
{
pTrs->Data[++(pTrs->top)] = item;
//return;
}
}
//出栈
//typedef pTree ElementType
ElementType Pop(stack* pTrs)
{
//出栈的时候如果栈为空,返回nullptr
if (pTrs->top == -1)
{
//printf("\n堆栈空\n");
//pTree p = NULL;
return NULL;
}
else
{
return (pTrs->Data[(pTrs->top)--]);
}
}
//判断栈是否为空
bool Empty_stack(pStack s)
{
return (s->top == -1);
}
//------------------------用栈实现二叉树的三种遍历--------------------------------
void sPreOrder(pTree t)//先序
{
/*
先序遍历
->1.打印左节点
2.节点入栈
3.访问下一个左节点,存在入栈
4.如果左节点下一个节点为空,使栈最上面的节点出栈并访问右节点
5.->1
*/
pStack s;
pTree p = t;
s = creat_stack();
while (p || !Empty_stack(s))
{
if (p)
{
printf("%c", p->data);
Push(s, p);
p = p->left;
}
else
{
p = Pop(s);
p = p->right;
}
}
}
void sInOrder(pTree t)
{
/*
中序遍历
->1.节点入栈,如果节点地左节点不为空 循环执行 step 1
2.左节点为空,使栈最上面节点出栈并访问当前节点的右节点
3.->1
*/
pStack s;
pTree p = t;
s = creat_stack();
while (p || !Empty_stack(s))
{
if (p)
{
//printf("%c", p->data);
Push(s, p);
p = p->left;
}
else
{
p = Pop(s);
printf("%c", p->data);
p = p->right;
}
}
}
void sPostOrder(pTree t)
{
/*
后序遍历
1.建立两个栈
由于后序遍历先访问左节点再访问右节点,所以入栈地时候先入右节点再入左节点
2.节点入栈,如果节点地右节点不为空 循环执行 step 1
3.右节点为空,使栈最上面节点出栈并访问当前节点的左节点
4.->1
*/
pStack s1;
pStack s2;
pTree p = t;
s1 = creat_stack();
s2 = creat_stack();
while (p || !Empty_stack(s2)) //树为空且栈为空,退出函数.
{
if (p)
{
//printf("%c", p->data);
Push(s1, p);
Push(s2, p);
p = p->right;
}
else
{
p = Pop(s2);
//printf("%c", p->data);
p = p->left;
}
}
while (!Empty_stack(s1))
{
p = Pop(s1);
printf("%c", p->data);
}
}
//-------------------------创建队列-------------------------
typedef struct
{
ElementType data[Maxsize];
int front, rear;
}SeqQueue, *pSeqQueue;
pSeqQueue creat_queue()
{
pSeqQueue Q = (pSeqQueue)malloc(sizeof(SeqQueue));
if (Q)
{
Q->front = -1;
Q->rear = -1;
}
return Q;
}
//判断队列是否为空
bool Empty_Queue(pSeqQueue q)
{
return (q->front == ((q->rear + 1) % Maxsize));
}
//入队列
void Qpush(pSeqQueue q, ElementType n)
{
if ((q->rear + 1) % Maxsize == q->front)
{
printf("队列满");
//return -1;
}
else
{
q->rear = (q->rear + 1) % Maxsize;
q->data[q->rear] = n;
//return 1;
}
}
//出队列
ElementType Qpop(pSeqQueue q)
{
if (q && q->front == q->rear)
{
//printf("队列空");
//return 1;
//exit(0);
return nullptr;
}
else
{
q->front = (q->front + 1) % Maxsize;
return q->data[q->front];
}
}
//层次遍历
void Printlevel(pTree t)
{
pTree temp = t;
pSeqQueue q;
q = creat_queue();
if (t == NULL)
{
printf("根节点为空"); //根节点为空,返回-1
}
else
{
Qpush(q, temp); //根节点(非指针)入队
}
while (!Empty_Queue(q)) //队列不为空
{
temp = Qpop(q); //指针出队//输出出队元素
if (temp)
printf("%c", temp->data);
else
break;
if (temp->left) //左子树不为空
{
Qpush(q, temp->left);//左子树入队
}
if (temp->right) //右子树不为空
{
Qpush(q, temp->right);//右子树入队
}
}
}
#endif
//.cpp
#include"BinaryTree.h"
#include"stdio.h"
int main()
{
pTree t;
t = create();
NodeCount(t);
int deep = depth(t);
printf("结点个数: %d 叶子结点个数: %d 深度: %d \n", jcount, ycount, deep);
int i = 1;
printf("1 for preorder | 2 for inorder | 3 for postorder | 4 for levelorder\n");
while (i)
{
scanf_s("%d", &i);
//int count2 = NodeCount(t);
switch (i)
{
case 1:
//preorder(t);
printf("Pre-Order: ");
sPreOrder(t);
printf("\n");
break;
case 2:
//inorder(t);
printf("In-Order: ");
sInOrder(t);
printf("\n");
break;
case 3:
//postorder(t);
printf("Post-Order: ");
sPostOrder(t);
printf("\n");
break;
case 4:
printf("Level-Order: ");
Printlevel(t);
printf("\n");
break;
}
}
return 0;
}
关于普通二叉树的创建、递归遍历、利用栈遍历、队列的层次遍历、节点、叶子个数,深度综合训练
最新推荐文章于 2022-07-06 13:59:34 发布