目录
层序遍历需要用到循环队列,表达式树需要用到堆栈。循环队列的创建按照普通代码创建就行,具体解释可以参考CSDN其他博主,堆栈的创建和使用用的链表实现。
对于二叉树来讲,加深的是对递归的理解和运用。
对于创建,遍历其中涉及详细解释可以自行参照其他博主博客,或者自行看书理解。下面是标题中所有代码。
代码
main.c
#include "transmit.h"
#define NoInfo 0
//先序递归创建二叉树
/*
BitTree CreateLink()
{
int data;
int temp;
BitTree T;
scanf_s("%d", &data); // 输入数据
if (data == -1) { // 输入-1 代表此节点下子树不存数据,也就是不继续递归创建
return NULL;
}
else {
T = (BitTree)malloc(sizeof(Tree)); // 分配内存空间
T->data = data; // 把当前输入的数据存入当前节点指针的数据域中
printf("请输入%d的左子树: ", data);
T->lchild = CreateLink(); // 开始递归创建左子树
printf("请输入%d的右子树: ", data);
T->rchild = CreateLink(); // 开始到上一级节点的右边递归创建左右子树
return T; // 返回根节点
}
}
*/
//层序创建二叉树
BitTree CreateLink()
{
int data=0;
scanf_s("%d", &data);
BitTree TreeRoot;
NODE NewQueue = creat();
//根节点
if (data != NoInfo)
{
TreeRoot = (BitTree)malloc(sizeof(Tree));
TreeRoot->data = data;
TreeRoot->lchild = TreeRoot->rchild = NULL;
addElement(NewQueue, TreeRoot);
}
else
{
return NULL;
}
/*利用队列保存每个节点地址,利用先进先出从上到下从左到右
依次创建二叉树,并依据队列是否为空(若二叉树有左右孩子(非零)时,
将此地址压入队列中;否则的话,地址置为空指针,防止野指针的出现)
循环创建*/
while (!isempty(NewQueue))
{
BitTree QueueLeaved= delElement(NewQueue);
printf("输入-%d-左节点数据:",QueueLeaved->data);
scanf_s("%d", &data);
if (data == NoInfo)
QueueLeaved->lchild = NULL;
else {
BitTree Transient = (BitTree)malloc(sizeof(Tree));
Transient->data = data;
Transient->lchild = Transient->rchild = NULL;
QueueLeaved->lchild = Transient;
addElement(NewQueue, QueueLeaved->lchild);
}
printf("输入-%d-右节点数据:", QueueLeaved->data);
scanf_s("%d", &data);
if (data == NoInfo)
QueueLeaved->rchild = NULL;
else {
BitTree Transient = (BitTree)malloc(sizeof(Tree));
Transient->data = data;
Transient->rchild = Transient->rchild = NULL;
QueueLeaved->rchild = Transient;
addElement(NewQueue, QueueLeaved->rchild);
}
}
//创建完毕,返回二叉树根节点地址
return TreeRoot;
}
// 先序遍历
void ShowXianXu(BitTree T) // 先序遍历二叉树
{
if (T == NULL) // 递归中遇到NULL,返回上一层节点
{
return;
}
printf("%d ", T->data);
ShowXianXu(T->lchild); // 递归遍历左子树
ShowXianXu(T->rchild); // 递归遍历右子树
}
// 中序遍历
void ShowZhongXu(BitTree T) // 先序遍历二叉树
{
if (T == NULL) // 递归中遇到NULL,返回上一层节点
{
return;
}
ShowZhongXu(T->lchild); // 递归遍历左子树
printf("%d ", T->data);
ShowZhongXu(T->rchild); // 递归遍历右子树
}
// 后序遍历
void ShowHouXu(BitTree T) // 后序遍历二叉树
{
if (T == NULL) // 递归中遇到NULL,返回上一层节点
{
return;
}
ShowHouXu(T->lchild); // 递归遍历左子树
ShowHouXu(T->rchild); // 递归遍历右子树
printf("%d ", T->data);
}
//层序遍历
void ShowCengXu(BitTree S)
{
if (S)
{
NODE Q = creat(); //创建空队列
BitTree Tools;
addElement(Q,S);
/*while (!isempty(Q))
{
Tools = delElement(Q);
printf("%d ", (&Tools)->data);
if ((&Tools)->lchild)
addElement(Q, (&Tools)->lchild);
if ((&Tools)->rchild)
addElement(Q, (&Tools)->rchild);
}*/
while (!isempty(Q))
{
Tools = delElement(Q);
printf("%d ", Tools->data);
if (Tools->lchild)
addElement(Q, Tools->lchild);
if (Tools->rchild)
addElement(Q, Tools->rchild);
}
}
else
return;
}
//叶节点遍历
void PreorderPrintLeaves(BitTree b)
{
if (b) {
if (!b->lchild && !b->rchild)
printf("--%d", b->data);
PreorderPrintLeaves(b->lchild);
PreorderPrintLeaves(b->rchild);
}
}
//二叉树高度
int GetHeight(BitTree S)
{
int Hl, Hr,Max;
if (S)
{
Hl = GetHeight(S->lchild);
Hr = GetHeight(S->rchild);
//左子树和右子树中最大的高度,加一(根节点)即为二叉树高度
Max = Hl > Hr ? Hl : Hr;
return (Max+1);
}
else
return 0;
}
//表达式树
BitTree1 createNode(char ch) {
BitTree1 newNode = (BitTree1)malloc(sizeof(Tree1));
if (!newNode) return NULL;
newNode->data = ch;
newNode->lchild = NULL;
newNode->rchild = NULL;
return newNode;
}
int isOperator(char ch) {
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' || ch == '^')
return 1;
return 0;
}
void RecurseCreatBT(SNODETree stack,char* string,int start, int end)
{
while (isOperator(string[++start]) == 0)
{
BitTree1 treeroot = createNode(string[start]);
push(stack, treeroot);
}
//start-->操作符
BitTree1 treeroot = createNode(string[start]);
treeroot->rchild = pop(stack);
treeroot->lchild = pop(stack);
push(stack, treeroot);
//递归创建表达式树
if(start != end)
RecurseCreatBT(stack, string, start, end);
}
BitTree1 buildTree(SNODETree stack,char*string,int start,int end)
{
if (start > end) return NULL;
BitTree1 treeroot = createNode(string[start]);
if (start == end) return treeroot;
push(stack, treeroot);
RecurseCreatBT(stack, string, start, end);
BitTree1 treeroot1 = pop(stack);
return treeroot1;
}
void inorderTraversal(BitTree1 root) {
if (root != NULL) {
inorderTraversal(root->lchild );
printf("%c", root->data);
inorderTraversal(root->rchild);
}
}
int main()
{
BitTree S;
printf("请输入第一个节点的数据:\n");
S = CreateLink(); // 接受创建二叉树完成的根节点
printf("先序遍历结果: \n");
ShowXianXu(S); // 先序遍历二叉树
printf("\n中序遍历结果: \n");
ShowZhongXu(S); // 中序遍历二叉树
printf("\n后序遍历结果: \n");
ShowHouXu(S); // 后序遍历二叉树
printf("\n层序遍历结果: \n");
ShowCengXu(S); //层序遍历二叉树
printf("\n二叉树所有叶节点: \n"); //遍历二叉树叶节点
PreorderPrintLeaves(S);
int Height = GetHeight(S);
printf("\n二叉树的高度: %d",Height); //二叉树高度
//构造表达式树
int flag = -1; //递归使用
SNODETree stack = CreatStack();
char expression[50]={'a','b','c','*','+','d','e','*','f','+','g','*','+','\0'};
/*printf("\nEnter the postfix expression: ");
scanf_s("%s", expression);*/
BitTree1 root = buildTree(stack,expression, 0, strlen(expression) - 1);
printf("\n表达式树中序遍历结果:\n");
inorderTraversal(root);
return 0;
}
transmit.h(主函数中未实现子函数传到头文件,在其他c文件中实现):
#include<stdbool.h>
#include<stdio.h>
#include<stdlib.h>
#include<assert.h>
#include <string.h>
#define maxsize 100
//二叉树节点
typedef struct Tree {
int data; // 存放数据域
struct Tree* lchild; // 遍历左子树指针
struct Tree* rchild; // 遍历右子树指针
}Tree, *BitTree;
//此二叉树节点用于表达式树的创建
typedef struct Tree1{
char data; // 存放数据域
struct Tree1* lchild; // 遍历左子树指针
struct Tree1* rchild; // 遍历右子树指针
}Tree1, *BitTree1;
//队列节点
typedef struct node* NODE;
struct node {
int front, end;
/*Tree data[maxsize]; */
BitTree data[maxsize];
};
//堆栈节点--链式存储
typedef struct SNode {
BitTree1 data;
struct SNode* next;
}SNODE,*SNODETree;
NODE creat();
bool isempty(NODE head);
void addElement(NODE head, BitTree dat);
BitTree delElement(NODE const head);
SNODETree CreatStack();
void push(SNODETree stack, BitTree1 treeroot);
BitTree1 pop(SNODETree stack);
Queue.c(队列的实现代码):
#include "transmit.h"
//typedef struct str {
// int data;
// struct str* next;
//}node;
/*队列的顺序存储*/
NODE creat()
{
int length = 0;
NODE head = (NODE)malloc(sizeof(struct node));
if (!head)
return NULL;
head->front = head->end = 0;
return head;
}
bool isempty(NODE head)
{
return head->end == head->front;
}
bool isFull(NODE head)
{
return (head->end + 1) % maxsize == head->front;
}
void addElement(NODE head ,BitTree dat)
{
assert(head);
if (isFull(head)) {
printf("队列已满!\n");
return;
}
else
head->data[(head->end++) % maxsize] = dat;
}
BitTree delElement(NODE const head)
{
assert(head);
BitTree value = head->data[head->front];
head->front = (++head->front) % maxsize;
return value;
}
Stack.c(堆栈代码的实现过程):
#include"transmit.h"
//堆栈--链式存储数据
SNODETree CreatStack() {
SNODETree stack = (SNODETree)malloc(sizeof(SNODE));
stack->next = NULL;
return stack;
}
void push(SNODETree stack, BitTree1 treeroot)
{
SNODETree stack1 = (SNODETree)malloc(sizeof(SNODE));
stack1->data = treeroot;
stack1->next = stack->next ;
stack->next = stack1;
}
BitTree1 pop(SNODETree stack)
{
BitTree1 B;
if (stack->next)
{
SNODETree stackT = stack->next;
B = stackT->data;
stack->next = stackT->next;
free(stackT);
return B;
}
else
{
printf("堆栈空");
return NULL;
}
}