二叉树的创建(先序创建,层序创建),先、中、后、层序遍历,叶节点和高度,表达式树的创建和中序遍历--------代码

        

目录

代码

结果打印


        层序遍历需要用到循环队列,表达式树需要用到堆栈。循环队列的创建按照普通代码创建就行,具体解释可以参考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;
    }
}




结果打印

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

天是蓝的嘛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值