5-8二叉树(链)的建立与C/C++输出

1.二叉树的建立与输出
参考https://blog.csdn.net/m0_63137469/article/details/124612827

输入说明:按照先序遍历方式建立树,左/右孩子为空输入-1即可。建立完成后p->data表示根节点的值,根的左孩子的值用p->lchild->data表示

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

typedef struct BiTNode {
	int data;
	struct BiTNode *lchild, *rchild;
}BiTNode, * BiTree;

BiTree creat_tree(void) {//建立
	int data;
	scanf_s("%d", &data);
	BiTree p = (BiTree)malloc(sizeof(BiTNode));
	BiTree prot = p;//第一个根节点的地址另外保存 
	p->data = data;

	if (data == -1) {
		return NULL;
	}
	else {
		printf("请输入%d左子树(输入-1代表不用创建): ", data);
		p->lchild = creat_tree();//新创建树,将地址赋值给根节点的左指针域
		printf("请输入%d右子树(输入-1代表不用创建): ", data);
		p->rchild = creat_tree();//新创建树,将地址赋值给根节点的右指针域
		return prot;
	}
}

int main() {
	printf("请输入第一个节点的数据:");
	BiTree p = creat_tree();//建立
	
	cout << "根节点,根节点的左孩子,根节点的右孩子的值依次为";
	cout << p->data<<" ";
	cout << p->lchild->data<<" ";
	cout << p->rchild->data;
	
	return 0;
}

输出结果
在这里插入图片描述

2.二叉树建立后用层序完整输出

(1)以下为层序遍历只输出非空结点代码

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

typedef struct BiTNode {
	int data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

BiTree creat_tree(void) {//建立,直接复制
	int data;
	scanf_s("%d", &data);
	BiTree p = (BiTree)malloc(sizeof(BiTNode));
	BiTree prot = p;
	p->data = data;
	if (data == -1) {
		return NULL;
	}
	else {
		printf("请输入%d左子树(输入-1代表不用创建): ", data);
		p->lchild = creat_tree();
		printf("请输入%d右子树(输入-1代表不用创建): ", data);
		p->rchild = creat_tree();
		return prot;
	}
}

typedef struct LinkNode {//队列基本操作相关
	BiTree data;
	struct LinkNode* next;
}LinkNode;
typedef struct {
	LinkNode* front, * rear;
}LinkQueue;
void InitQueue(LinkQueue& Q) {//初始化
	Q.front = Q.rear = (LinkNode*)malloc(sizeof(LinkNode));
	Q.front->next = NULL;
}
void EnQueue(LinkQueue& Q, BiTree x) {
	LinkNode* s = (LinkNode*)malloc(sizeof(LinkNode));
	s->data = x;
	s->next = NULL;
	Q.rear->next = s;
	Q.rear = s;
}
bool DeQueue(LinkQueue& Q, BiTree &x) {
	if (Q.front == Q.rear)//判空
		return false;
	LinkNode* p = Q.front->next;
	x = p->data;
	Q.front->next = p->next;
	if (Q.rear == p)
		Q.rear = Q.front;
	free(p);
	return true;
}

void LeverOrder(BiTree T) {//【层序遍历输出】
	LinkQueue Q;
	InitQueue(Q);//初始化辅助队列
	BiTree p;
	EnQueue(Q, T);//根结点入队
	while (Q.front!=Q.rear) {//队列不空则循环
		DeQueue(Q, p);//队头结点出队
		cout << p->data;
		if (p->lchild != NULL)
			EnQueue(Q, p->lchild);//左孩子入队
		if (p->rchild != NULL)
			EnQueue(Q, p->rchild);//右孩子入队
	}
}

int main() {
	printf("请输入第一个节点的数据:");
	BiTree p = creat_tree();//建立二叉树
	LeverOrder(p);//层序输出
	return 0;
}

(2)以下为层序遍历以完全二叉树形式输出代码(空结点用0表示)

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

typedef struct BiTNode {
	int data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

BiTree creat_tree(void) {//建立,直接复制
	int data;
	scanf_s("%d", &data);
	BiTree p = (BiTree)malloc(sizeof(BiTNode));
	BiTree prot = p;
	p->data = data;
	if (data == -1) {
		return NULL;
	}
	else {
		printf("请输入%d左子树(输入-1代表不用创建): ", data);
		p->lchild = creat_tree();
		printf("请输入%d右子树(输入-1代表不用创建): ", data);
		p->rchild = creat_tree();
		return prot;
	}
}

typedef struct LinkNode {//结点
	BiTree data;
	struct LinkNode* next;
}LinkNode;

#define MaxSize 100
typedef struct {//定义
	BiTree data[MaxSize];//存放元素
	int front, rear;//头尾指针
}SqQueue;

void InitQueue(SqQueue& Q) {//初始化
	Q.rear = Q.front = 0;
}

bool IsEmpty(SqQueue Q) {//判空
	if (Q.rear == Q.front)
		return true;
}

int count2 = 0;//记录结点总数
int CountPreOrder(BiTree T) {//借用先序遍历统计结点个数
	if (T != NULL)
	{
		count2++;
		CountPreOrder(T->lchild);//访问左子树
		CountPreOrder(T->rchild);//访问右子树
	}
	return count2;
}

void LeverOrder(BiTree T,int countsum) {//层序遍历输出部分
	int temp=0;//计数
	SqQueue Q;
	InitQueue(Q);//初始化辅助队列
	BiTree p;
	int a[100];//辅助数组
	int i = 0;

	Q.data[Q.rear] = T;
	Q.rear = Q.rear + 1;

	while (Q.front!=Q.rear) {//队列不空则循环
		p = Q.data[Q.front];
		if (!p) {//用0表示的空结点放入数组
			a[i] = 0;
			i++;
			temp++;//记录放入的空结点数量
		}
		else {
			a[i] = p->data;//非空结点放入数组
			i++;
		}
		if (i == temp + countsum)
			break;
		Q.front = Q.front + 1;
		if (p && p->lchild != NULL) {
			Q.data[Q.rear] = p->lchild;//左孩子入队
		}
		else {
			Q.data[Q.rear] = NULL;
		}
		Q.rear = Q.rear + 1;

		if (p && p->rchild != NULL) {
			Q.data[Q.rear] = p->rchild;//右孩子入队	
		}
		else {
			Q.data[Q.rear] = NULL;
		}
		Q.rear = Q.rear + 1;
	}
	for (int j = 0; j < i; j++) {//输出数组
		cout << a[j] << " ";
	}
}

int main() {
	printf("请输入第一个节点的数据:");
	BiTree p = creat_tree();//建立二叉树
	int count=CountPreOrder(p);
	//swap(p);//新增代码
	LeverOrder(p,count);
	return 0;
}

效果如图
在这里插入图片描述

3.应用一
如:假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度

算法思想:采用层次遍历的算法,设置变量level记录当前结点所在的层数,设置变量last指向当前层的最右结点,每次层次遍历出队时与last指针比较,若两者相等,则层数加1,并让last指向下一层的最右结点,直到遍历完成。level的值即为二叉树的高度。
在这里插入图片描述
实现代码

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

typedef struct BiTNode {
	int data;
	struct BiTNode *lchild, *rchild;
}BiTNode, * BiTree;

BiTree creat_tree(void) {//建立,直接复制
	int data;
	scanf_s("%d", &data);
	BiTree p = (BiTree)malloc(sizeof(BiTNode));
	BiTree prot = p;
	p->data = data;
	if (data == -1) {
		return NULL;
	}
	else {
		printf("请输入%d左子树(输入-1代表不用创建): ", data);
		p->lchild = creat_tree();
		printf("请输入%d右子树(输入-1代表不用创建): ", data);
		p->rchild = creat_tree();
		return prot;
	}
}

#define MaxSize 100
int Btdepth(BiTree T) {//【本题算法】
	if (!T)
		return 0;
	int front = -1, rear = -1;
	int last = 0, level = 0;
	BiTree Q[MaxSize];
	Q[++rear] = T;
	BiTree p;
	while (front < rear) {
		p = Q[++front];
		if (p->lchild)
			Q[++rear] = p->lchild;
		if (p->rchild)
			Q[++rear] = p->rchild;
		if (front == last) {
			level++;
			last = rear;
		}
	}
	return level;
}
int main() {
	printf("请输入第一个节点的数据:");
	BiTree p = creat_tree();//建立二叉树
	
	int level=Btdepth(p);//新增代码
	cout << "层数为:"<< level;
	return 0;
}

结果
在这里插入图片描述

4.应用二
交换所有结点的左右子树
在这里插入图片描述

#include <stdio.h>
#include <malloc.h>
#include <iostream>
using namespace std;

typedef struct BiTNode {
	int data;
	struct BiTNode* lchild, * rchild;
}BiTNode, * BiTree;

BiTree creat_tree(void) {//建立,直接复制
	int data;
	scanf_s("%d", &data);
	BiTree p = (BiTree)malloc(sizeof(BiTNode));
	BiTree prot = p;
	p->data = data;
	if (data == -1) {
		return NULL;
	}
	else {
		printf("请输入%d左子树(输入-1代表不用创建): ", data);
		p->lchild = creat_tree();
		printf("请输入%d右子树(输入-1代表不用创建): ", data);
		p->rchild = creat_tree();
		return prot;
	}
}

typedef struct LinkNode {//结点
	BiTree data;
	struct LinkNode* next;
}LinkNode;

#define MaxSize 100
typedef struct {//定义
	BiTree data[MaxSize];//存放元素
	int front, rear;//头尾指针
}SqQueue;

void InitQueue(SqQueue& Q) {//初始化
	Q.rear = Q.front = 0;
}

bool IsEmpty(SqQueue Q) {//判空
	if (Q.rear == Q.front)
		return true;
}

int count2 = 0;
int CountPreOrder(BiTree T) {//借用先序遍历统计结点个数
	if (T != NULL)
	{
		count2++;
		CountPreOrder(T->lchild);//访问左子树
		CountPreOrder(T->rchild);//访问右子树
	}
	return count2;
}

void LeverOrder(BiTree T,int countsum) {
	int temp=0;//计数,看是否达到最后一个结点
	SqQueue Q;
	InitQueue(Q);//初始化辅助队列
	BiTree p;
	int a[100];//辅助数组
	int i = 0;

	Q.data[Q.rear] = T;
	Q.rear = Q.rear + 1;

	while (Q.front!=Q.rear) {//队列不空则循环
		p = Q.data[Q.front];
		if (!p) {
			a[i] = 0;
			i++;
			temp++;
		}
		else {
			a[i] = p->data;
			i++;
		}
		if (i == temp + countsum)
			break;
		Q.front = Q.front + 1;
		if (p && p->lchild != NULL) {
			Q.data[Q.rear] = p->lchild;//左孩子入队
			
		}
		else {
			Q.data[Q.rear] = NULL;
			
		}
		Q.rear = Q.rear + 1;

		if (p && p->rchild != NULL) {
			Q.data[Q.rear] = p->rchild;//右孩子入队
			
		}
		else {
			Q.data[Q.rear] = NULL;
			
		}
		Q.rear = Q.rear + 1;
	}
	for (int j = 0; j < i; j++) {
		cout << a[j] << " ";
	}
}

void swap(BiTree& T) {//【本题算法】
	if (T) {
		swap(T->lchild);
		swap(T->rchild);
		BiTree temp;
		temp = T->lchild;
		T->lchild = T->rchild;
		T->rchild = temp;
	}
}

int main() {
	printf("请输入第一个节点的数据:");
	BiTree p = creat_tree();//建立二叉树
	int count=CountPreOrder(p);
	swap(p);//新增代码
	LeverOrder(p,count);
	return 0;
}

结果
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
代码如下: ```c++ #include<iostream> #include<stack> using namespace std; typedef struct BiTNode{ char data; struct BiTNode *lchild, *rchild; }BiTNode, *BiTree; // 根据带空的先缀串建立一棵二叉树 void CreateBiTree(BiTree &T){ char ch; if(cin>>ch){ if(ch == '#'){ T = NULL; } else{ T = new BiTNode; T->data = ch; CreateBiTree(T->lchild); CreateBiTree(T->rchild); } } } // 先序遍历 void PreOrder(BiTree T){ if(T){ cout<<T->data; PreOrder(T->lchild); PreOrder(T->rchild); } } // 中序遍历 void InOrder(BiTree T){ if(T){ InOrder(T->lchild); cout<<T->data; InOrder(T->rchild); } } // 后序遍历 void PostOrder(BiTree T){ if(T){ PostOrder(T->lchild); PostOrder(T->rchild); cout<<T->data; } } // 计算叶子节点的数量 int CountLeaf(BiTree T){ if(!T){ return 0; } if(!T->lchild && !T->rchild){ return 1; } return CountLeaf(T->lchild) + CountLeaf(T->rchild); } // 计算二叉树的深度 int Depth(BiTree T){ if(!T){ return 0; } int ldepth = Depth(T->lchild); int rdepth = Depth(T->rchild); return max(ldepth, rdepth) + 1; } // 非递归中序遍历 void NonRecInOrder(BiTree T){ stack<BiTree> s; BiTree p = T; while(p || !s.empty()){ if(p){ s.push(p); p = p->lchild; } else{ p = s.top(); s.pop(); cout<<p->data; p = p->rchild; } } } int main(){ BiTree T; CreateBiTree(T); PreOrder(T); cout<<endl; InOrder(T); cout<<endl; PostOrder(T); cout<<endl; cout<<CountLeaf(T)<<endl; cout<<Depth(T)<<endl; NonRecInOrder(T); cout<<endl; return 0; } ``` 对于输入用例 "AB#C##D##",输出结果为: ABCD BCAD CBDA 2 3 BCAD 对于输入用例 "-+a##b##/d##e##",输出结果为: -+ab/de a+b-d/e ab+de/- 4 3 a+b-d/e
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

卡__卡

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

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

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

打赏作者

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

抵扣说明:

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

余额充值