二叉树基本 *** 作(16个)

二叉树基本 *** 作(16个),第1张

本代码采用三个文件编写,分别是头文件,函数的文件,和主文件,除了后三个代码用c++编写(用c语言太麻烦了),其余全是c语言,目前就是只有一个清除树代码运行有错误,当时找了好久没有找出哪个地方出错,若找到后续会更新改正,欢迎在讨论区交流。

 头文件:

#pragma once
#include 
#include 
#include 
#include 
#include 
#include 
using namespace std;
typedef  char TElemType;
typedef struct BinNode  //定义二叉树结点:二叉链表结构 (5分)
{
	int data;
	struct BinNode* Ichild, * Rchild;
}BinNode;
typedef struct BinNode* BinTree;


void CreateBinTree(BinTree &bt);//创建二叉树
void PreOrderBinTree(BinTree &bt);//先序遍历
void InOrderBinTree(BinTree &bt);//中序遍历
void PostOrderBinTree(BinTree &bt);//后序遍历
BinNode* FindNode(BinTree bt, TElemType x);//查找值为F的结点
int Size(BinTree bt);//求结点个数
int Height(BinTree bt);//求树的高度
BinNode* Parent(BinTree bt, BinNode* p);//查找二叉树中某个结点p的父节点
BinNode* LeftChild(BinNode* p);//查找结点p的左孩子结点 
BinNode* RightChild(BinNode* p);//查找结点p的右孩子结点
BinNode* Copy(BinTree bt);//用bt拷贝newbt树
void ClearBinTree(BinTree &bt);// 清除树
void LevelOrder(BinTree bt);//层次遍历
void PreorderTraverse(BinTree bt);//先序非递归遍历
void InorderTraverse(BinTree bt);//非递归中序遍历

函数文件:

注意:*&bt:bt离着*,&谁近他就是什么类型,所以这里是&引用型(别名),再加上*这里就表示引用型指针,想到与传入指针得本身,可以对指针的指向和值都进行改变。

#include "touwen.h"//传入 函数 *&p是传入指针p本身 ,可以对指针的指向做更改,如p++,也可以更改指针指向的值

//#法线序创建二叉树
void CreateBinTree(BinTree &bt) {
	char ch;
	cin >> ch;
	if (ch != '#'){
		bt = (BinTree)malloc(sizeof(BinTree));
		bt->data = ch;
		CreateBinTree(bt->Ichild);//这里就对bt指针改变了,所以需要用*&的形式
		CreateBinTree(bt->Rchild);
	}
	else {
		bt = NULL;
	}

}
//先序遍历
void PreOrderBinTree(BinTree &bt) //先序遍历访问二叉树
{
	if (bt!= NULL)
	{
		putchar(bt->data);//在屏幕上显示字符, 若直接用cout<data, 则输出的字符的ASCII码.
		printf(" ");
		PreOrderBinTree(bt->Ichild);
		PreOrderBinTree(bt->Rchild);
	}
	else
	{
		return;
	}
}
//中序遍历
void InOrderBinTree(BinTree& bt) //先序遍历访问二叉树
{
	if (bt != NULL)
	{
		InOrderBinTree(bt->Ichild);
		putchar(bt->data);//在屏幕上显示字符, 若直接用cout<data, 则输出的字符的ASCII码.
		printf(" ");
		InOrderBinTree(bt->Rchild);
	}
	else
	{
		;
	}
}//后序遍历
void PostOrderBinTree(BinTree& bt) //先序遍历访问二叉树
{
	if (bt != NULL)
	{
		
		PostOrderBinTree(bt->Ichild);
		PostOrderBinTree(bt->Rchild);
		putchar(bt->data);//在屏幕上显示字符, 若直接用cout<data, 则输出的字符的ASCII码.
		printf(" ");
	}
	else
	{
		;
	}
}
//查找在二叉树中查找值为x的结点
BinNode* FindNode(BinTree bt, TElemType x) {
	BinTree temp;
	temp = bt;
	
	if (bt != NULL)
	{ 
		if (temp->data == x) {
			return bt;
		}
		FindNode(temp->Ichild,x);//先看左子树
		if(!temp)FindNode(temp->Rchild,x);//左子树为空,才可以进入右子树,若左子树不为空,跳过这一步,返回temp指针。
	}
	else
	{
		return NULL;
	}
}
//求结点个数
int Size(BinTree bt) {
	if (bt == NULL) {
		return 0;
	}
	else {
		return Size(bt->Ichild)+ Size(bt->Rchild)+1;
	}
}
//求树的高度
int Height(BinTree bt) {
	int m = 0, n = 0;
	if (bt == NULL) {
		return 0;
	}
	else {
		m = Height(bt->Ichild);
		n = Height(bt->Rchild);
		if (m > n) {
			return (m + 1);
		}
		else {
			return (n + 1);
		}
	}
}
//查找二叉树中某个结点p的父节点
BinNode* Parent(BinTree bt, BinNode* p) {
	if (bt == NULL || bt == p || p == NULL) {
		return NULL;//T==p说明p是头结点,头节点没有父节点
	}
	if (bt->Ichild == p || bt->Rchild == p) {
		return bt;
	}
	BinTree temp = Parent(bt->Ichild, p);
	if (temp != NULL) {
		return temp;
	}
	else {
		return Parent(bt->Rchild, p);
	}
}
//查找结点p的左孩子结点 
BinNode* LeftChild(BinNode* p) {
	if (p == NULL||p->Ichild==NULL) {
		return NULL;
	}
	else {
		return p->Ichild;
	}
}
//查找结点p的右孩子结点
BinNode* RightChild(BinNode* p) {
	if (p == NULL || p->Rchild == NULL) {
		return NULL;
	}
	else {
		return p->Rchild;
	}
}
//用bt拷贝newbt树
BinNode * Copy(BinTree bt) {
	if (bt == NULL) {
		return NULL;
	}
	else {
		BinTree newbt = (BinTree)malloc(sizeof(BinNode ));
		BinTree newIchild = NULL;
		BinTree newRchild = NULL;
		newIchild = Copy(bt->Ichild);
		newRchild = Copy(bt->Rchild);
		newbt->data = bt->data;
		newbt->Ichild = newIchild;
		newbt->Rchild = newRchild;
		return newbt;
	}
}
//清空二叉树,其实就是后序遍历删除
void ClearBinTree(BinTree &bt) {
	if (bt != NULL) {
		ClearBinTree(bt->Ichild);
		ClearBinTree(bt->Rchild);
		free(bt);
		bt = NULL;
	}
	
}
//层次遍历
queue qu;
void LevelOrder(BinTree bt) {
	qu.push(bt);
	cout << "层次遍历为:";
	while(!qu.empty()) {
		printf("%c ", qu.front()->data);
		if (qu.front()->Ichild != NULL) {
			qu.push(qu.front()->Ichild);
		}
		if (qu.front()->Rchild != NULL) {
			qu.push(qu.front()->Rchild);
		}
		qu.pop();
	}
}
stack sta;
//先序非递归遍历
void PreorderTraverse(BinTree bt) {
	cout << "先序遍历结果为:";
	while (bt || !sta.empty()) {
		if (bt) {
			printf("%c ", bt->data);
			sta.push(bt);
			bt = bt->Ichild;
		}
		else {
			bt = sta.top()->Rchild;
			sta.pop();
		}
	}
	return;
}
//非递归种序遍历
void InorderTraverse(BinTree bt) {
	cout << "中序遍历结果为:";
	while (bt || !sta.empty()) {
		if (bt) {
			sta.push(bt);
			bt = bt->Ichild;
		}
		else {
			printf("%c ", sta.top()->data);
			bt = sta.top()->Rchild;
			sta.pop();
		}
	}
	return ;
}

mian文件:

这个文件我把功能都分别注释掉了,想运行哪一个可以把注释去掉就可以,我这里利用的时DEF###B##作为输入案例,大家也可以使用别的数据进行测试,但要保证时是用正确的#法建立二叉树的格式输入

#include "touwen.h"
int main() {
	BinTree T = NULL;
	printf("按先序遍历输入二叉树结点:");
	CreateBinTree(T);//DEF###B##(课本用例子)
	PreOrderBinTree(T);//先序
	
	//InOrderBinTree(T);//中序
	
	//PostOrderBinTree(T);//后续

	/*char x = 'F';//查找值为x的结点
	BinTree p = FindNode(T, x);
	printf("查找值为F的结点值为:%c\n", p->data);*/

	//int a = Size(T);//结点个数
	//printf("二叉树结点个数为:%d\n", a);
	
	//int a = Height(T);//树的高度
	//printf("二叉树的高度为:%d\n", a);

     /* char x = 'F';//查找值为x的结点
	BinTree p = FindNode(T, x);
	printf("查找值为F的结点值为:%c\n", p->data);
	 p = Parent(T, p);//查找二叉树中某个结点p的父节点,和查找x值结点搭配使用测试
	printf("查找值为F的父结点值为:%c", p->data);*/

	/*char x = 'E';
	BinTree p = FindNode(T, x);
	printf("查找值为F的结点值为:%c\n", p->data);
	p = LeftChild(p);//查找结点p的左孩子结点 
	printf("查找值为E的左孩子值为:%c", p->data);*/

	/*char x = 'D';
	BinTree p = FindNode(T, x);
	printf("查找值为D的结点值为:%c\n", p->data);
	p = RightChild(p);//查找结点p的左孩子结点 
	printf("查找值为D的右孩子值为:%c", p->data);*/

	//BinTree temp = Copy(T);
	//PreOrderBinTree(temp);//先序

	//ClearBinTree(T);//清空二叉树
	//PreOrderBinTree(T);

	//LevelOrder(T);//层次遍历

	//PreorderTraverse(T);//非递归先序遍历

	//InorderTraverse(T);//非递归中序遍历


	return 0;
}

不懂得可以在讨论区交流!

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/789167.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-05
下一篇 2022-05-05

发表评论

登录后才能评论

评论列表(0条)

保存