二叉树的前中序遍历(非递归+递归)

一、头文件

1.stack.h 栈头文件

#pragma once
#include <stdio.h>
#include <iostream>
#include "tree.h"

using namespace std;

#define MaxSize 128

typedef struct _SqStack
{
	Bnode *base;//栈底指针
	Bnode *top;//栈顶指针 
}SqStack;

bool InitStack(SqStack &S)
{
	S.base = new Bnode[MaxSize];
	
	if(!S.base)
		return false;
	
	S.top = S.base;
	
	return true;
}

bool PushStack(SqStack &S,Bnode e)
{
	if(S.top-S.base == MaxSize)
		return false;
	
	*(S.top++)=e;
	
	return true;
}

bool PopStack(SqStack &S,Bnode &e)
{
	if(S.base == S.top)
		return false;
	
	e = *(--S.top);
	
	return true; 
}

bool PopStack1(SqStack &S)
{
	if(S.base == S.top)
		return false;
	
	S.top--;
	
	return true; 
} 

Bnode* GetTop(SqStack &S)
{
	if(S.top != S.base)//非空
	
		return S.top-1;
	else
		return NULL; 
}

int GetSize(SqStack &S)
{
	return (S.top-S.base);
} 

bool IsEmpty(SqStack &S)
{
	if(S.top == S.base)
		return true;
	else
		return false;
}

void DestroyStack(SqStack &S)
{
	if(S.base)
		free(S.base);
		
	S.base = NULL;
	S.top  = NULL;
}

2.tree.h 树头文件

#ifndef __TREE_H__
#define __TREE_H__
#define MAX_NODE 1024
#define isLess(a, b) (a<b)
#define isEqual(a, b) (a==b)

typedef int ElemType;
typedef struct _Bnode {
	ElemType data; //元素类型
	struct _Bnode* lchild, * rchild;//指向左右孩子节点
}Bnode, Btree;
#endif

二、前中序遍历

1.前序遍历(递归)

/************************
* 采用递归方式实现前序遍历
*************************/
void PreOrderRec(Btree* root)
{
	if (root == NULL)
	{
		return;
	}
	printf("- %d -", root->data);
	PreOrderRec(root->lchild);
	PreOrderRec(root->rchild);
}

在这里插入图片描述

2.前序遍历----借助栈

/************************
* 借助栈实现前序遍历
*************************/
void PreOrder(Btree* root)
{
	Bnode cur;
	if (root == NULL)
	{
		return;
	}
	SqStack stack;
	InitStack(stack);
	PushStack(stack, *root); //头节点先入栈
	while (!(IsEmpty(stack))) //栈为空,所有节点均已处理
	{
		PopStack(stack, cur); //要遍历的节点
		printf("- %d -", cur.data);
		if (cur.rchild != NULL)
		{
			PushStack(stack, *(cur.rchild)); //右子节点先入栈,后处理
		}
		if (cur.lchild != NULL)
		{
			PushStack(stack, *(cur.lchild)); //左子节点后入栈,接下来先处理
		}
	}
	DestroyStack(stack);
}

在这里插入图片描述

3.中序遍历(递归)

/*中序遍历--递归*/
void PreOrderRec2(Btree *root)
{
	if(root == NULL)
		return ;

	PreOrderRec2(root->lchild);
	printf("-%d-",root->data);
	PreOrderRec2(root->rchild);	
	
} 

在这里插入图片描述

4.中序遍历----借助栈

/*中序遍历--借助栈*/
void PreOrder2(Btree* root)
{
	Bnode* cur = root;
	Bnode cur1;
	if(root == NULL)
		return  ;
		
	SqStack stack;
	
	InitStack(stack);

	while(!(IsEmpty(stack))|| cur!=NULL) 
	{
		while(cur!=NULL)
		{
			PushStack(stack,*cur);
			cur = cur->lchild;
		}

		PopStack(stack,cur1);//出栈 (根节点,记录器)  
		printf("-%d-",cur1.data);//打印出栈元素

		if(cur1.rchild!=NULL)
			cur = cur1.rchild;
	}
	DestroyStack(stack);	

}

在这里插入图片描述

5.结点上树

/*结点上树*/
bool InsertBtree(Btree** root, Bnode* node) {
	Bnode* tmp = NULL;
	Bnode* parent = NULL;
	if (!node) {
		return false;
	}
	else {//清空新节点的左右子树
		node->lchild = NULL;
		node->rchild = NULL;
	}
	if (*root) {//存在根节点
		tmp = *root;
	}
	else { //不存在根节点
		*root = node;
		return true;
	}
	while (tmp != NULL) {
		parent = tmp;//保存父节点
		//printf("父节点: %d\n", parent->data);
		if (isLess(node->data, tmp->data)) {
			tmp = tmp->lchild;
		}
		else {
			tmp = tmp->rchild;
		}
	}
	//若该树为空树,则直接将 node 放置在根节点上
	if (isLess(node->data, parent->data)) {//找到空位置后,进行插入
		parent->lchild = node;
	}
	else {
		parent->rchild = node;
	}
	return true;
}

6.删除树结点

/*删除树结点*/
Btree* DeleteNode(Btree* root, int key, Bnode*& deletedNode) {
	if (root == NULL)return NULL;
	if (root->data > key)
	{
		root->lchild = DeleteNode(root->lchild, key, deletedNode);
		return root;
	}
	if (root->data < key)
	{
		root->rchild = DeleteNode(root->rchild, key, deletedNode);
		return root;
	}
	deletedNode = root;
	//删除节点不存在左右子节点,即为叶子节点,直接删除
	if (root->lchild == NULL && root->rchild == NULL)return NULL;
	//删除节点存在右子节点,直接用右子节点取代删除节点
	if (root->lchild == NULL && root->rchild != NULL)return root->rchild;
	//删除节点存在左子节点,直接用左子节点取代删除节点
	if (root->lchild != NULL && root->rchild == NULL)return root->lchild;
	删除节点存在左右子节点,直接用左子节点最大值取代删除节点
	int val = findMax(root->lchild);
	root->data = val;
	root->lchild = DeleteNode(root->lchild, val, deletedNode);
	return root;
}

7.1查找结点(递归)

/************************
* 采用递归方式查找结点
*************************/
Bnode* QueryByRec(Btree* root, ElemType e) {
	if (isEqual(root->data, e) || NULL == root) {
		return root;
	}
	else if (isLess(e, root->data)) {
		return QueryByRec(root->lchild, e);
	}
	else {
		return QueryByRec(root->rchild, e);
	}
}

7.2查找结点(非递归)

/**
* 使用非递归方式查找结点
*/
Bnode* QueryByLoop(Bnode* root, int e) {
	while (NULL != root && !isEqual(root->data, e)) {
		if (isLess(e, root->data)) {
			root = root->lchild;
		}
		else {
			root = root->rchild;
		}
	}
	return root;
}

8.入口函数

int main(void)
{
	int test[]={19, 7, 25, 5, 11, 15, 21, 61};

	Bnode * root=NULL, *node =NULL;

	node = new Bnode;
	node->data = test[0];

	InsertBtree(&root, node);//插入根节点

	for(int i=1;i<sizeof(test)/sizeof(test[0]);i++)
	{
		node = new Bnode;
		node->data = test[i];
		if(InsertBtree(&root, node))
		{
		printf("节点 %d 插入成功\n", node->data);
		}
	}

	printf("前序遍历结果: \n");
	PreOrder(root);
	printf("\n");
	system("pause");

	//二叉搜索树删除
	printf("删除节点 15\n");
	Bnode *deletedNode = NULL;
	root = DeleteNode(root, 15, deletedNode);
	printf("二叉搜索树删除节点 15, %s\n", deletedNode?"删除成功":"删除不成功,节点不存在");
	if(deletedNode) delete deletedNode;
	printf("删除后,再次前序遍历结果: \n");
	PreOrder2(root);
	printf("\n");

	//二叉搜索树查找节点
	Bnode * node1 = QueryByLoop(root, 20);
	printf("搜索二叉搜索树,节点 20 %s\n", node1?"存在":"不存在");
	Bnode * node2 = QueryByLoop(root, 21);
	printf("搜索二叉搜索树,节点 21 %s\n", node2?"存在":"不存在");
	system("pause");
	return 0;
}

9.测试结果

在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值