数据结构中二叉树相关操作

   二叉树是一种重要的数据结构,关于二叉树的相关操作尤为重要,其中主要操作大概分为:建树,遍历,返回二叉树的相关参数。 

  其中较难的是非递归遍历二叉树,直接给出代码读者若有疑问欢迎随时指点:

 

#pragma once 

#include  "Queue.h"
#include "Stack.h"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

#define MAX(x,y) (x)>(y)?(x):(y)

typedef char DataType;

typedef struct TreeNode{
	struct TreeNode  *pLeft;
	struct  TreeNode *pRight;
	DataType data;
}TreeNode;
//初始化
TreeNode * CreateRoot(DataType data){
	TreeNode *pRoot = (TreeNode *)malloc(sizeof(TreeNode));
	assert(pRoot);
	pRoot->data = data;
	pRoot->pLeft = NULL;
	pRoot->pRight = NULL;
	
	return pRoot;
}
//建一颗二叉树
TreeNode * CreateTree(DataType preOrder[], int size, int *pIndex){
	if (*pIndex >= size){
		return NULL;
	}
	if (preOrder[*pIndex] == '#'){
		*pIndex+=1;
		return NULL;
	}
	TreeNode *pRoot = CreateRoot(preOrder[*pIndex]);
	*pIndex+=1;
	pRoot->pLeft = CreateTree(preOrder,  size,  pIndex);
	pRoot->pRight = CreateTree(preOrder,  size, pIndex);
	return pRoot;
}
// 前序,递归
void PreOrder(TreeNode *pRoot){
	if (pRoot == NULL){
		return ;
	}
	printf("%c ",pRoot->data);
	PreOrder(pRoot->pLeft);
	PreOrder(pRoot->pRight);
}
// 中序,递归
void InOrder(TreeNode *pRoot){
	if (pRoot == NULL){
		return;
	}
	InOrder(pRoot->pLeft);
	printf("%c ", pRoot->data);
	InOrder(pRoot->pRight);
}
// 后序,递归
void PostOrder(TreeNode *pRoot){
	if (pRoot == NULL){
		return;
	}
	PostOrder( pRoot->pLeft);
	PostOrder( pRoot->pRight);
	printf("%c ", pRoot->data);
}
//树的结点
int GetSize(TreeNode *pRoot){
	if (pRoot == NULL){
		return;
	}
	return GetSize(pRoot->pLeft) + GetSize(pRoot->pRight) + 1;
}
//叶子的结点
int GetLeafSize(TreeNode *pRoot){
	if (pRoot == NULL){
		return;
	}
	if (pRoot->pLeft == NULL && pRoot->pRight == NULL){
		return 1;
	}
	return GetLeafSize(pRoot->pLeft) + GetLeafSize(pRoot->pRight);
}
//K层 叶子结点
int GetKLevelSize(TreeNode *pRoot, int k){
	assert(k >= 1);
	if (pRoot == NULL){
		return;
	}
	if (k==1){
		return 1;
	}
	return GetKLevelSize(pRoot->pLeft, k - 1) + GetKLevelSize(pRoot->pRight, k - 1);

}
// 找到,返回结点地址,否则返回 NULL
TreeNode *Find(TreeNode *pRoot, DataType data){
	if (pRoot == NULL){
		return;
	}
	if (pRoot->data == data){
		return pRoot;
	}
	TreeNode *pFind=Find(pRoot->pLeft, data);
	if (pFind != NULL){
		return pFind;
	}
	return Find(pRoot->pRight, data);
}
// 求树的高度/深度
int GetHeight(TreeNode *pRoot){
	if (pRoot == NULL){
		return;
	}
	if (pRoot->pLeft == NULL&&pRoot->pRight == NULL){
		return 1;
	}
	int left = GetHeight(pRoot->pLeft);
	int right = GetHeight(pRoot->pRight);
	return MAX((left), (right)) + 1;
}
//非递层序遍历
void LevelOrder(TreeNode *pRoot){
	assert(pRoot != NULL);
	Queue Queue;
	TreeNode *Front;
	QueueInit(&Queue);
	QueuePush(&Queue, pRoot);
	while (!QueueIsEmpty(&Queue)){

		Front = QueueFront(&Queue);
		QueuePop(&Queue);
		printf("%c ", Front->data);
		if (Front->pLeft != NULL){
			QueuePush(&Queue, Front->pLeft);
		}
		if (Front->pRight != NULL){
			QueuePush(&Queue, Front->pRight);
		}
	}
}
//判断是否为完全二叉树,是返回1,否返回0.
int IsComlelement(TreeNode *pRoot){
	if (pRoot == NULL){
		return 1;
	}
	Queue Queue;
	TreeNode *Front;
	QueueInit(&Queue);
	QueuePush(&Queue, pRoot);
	while (!QueueIsEmpty(&Queue)){
		Front = QueueFront(&Queue);
		QueuePop(&Queue);
		if (Front == NULL){
			break;
		}
		QueuePush(&Queue, Front->pLeft);
		QueuePush(&Queue, Front->pRight);
	}
	while (!QueueIsEmpty(&Queue)){
		Front = QueueFront(&Queue);
		QueuePop(&Queue);
		if (Front == NULL){
			return 1;
		}
		return 0;
	}
	return;
}

//非递归前序
void PreOrder1(TreeNode *pTree)
{
	assert(pTree != NULL);
	Stack stack;
	StackInit(&stack);
	TreeNode *pcur = pTree;
	TreeNode *pTop=NULL;
	while (pcur != NULL || !StackIsEmpty(&stack))
	{
		while (pcur != NULL){
			printf("%c ", pcur->data);
			StackPush(&stack, pcur);
			pcur = pcur->pLeft;
		}
		pTop = getFirst(&stack);
		StackPop(&stack);
		pcur = pTop->pRight;
	}
}
//非递归中序
void inOrder1(TreeNode *pTree){
	assert(pTree != NULL);
	TreeNode* pcur = pTree;
	TreeNode*Top = NULL;
	Stack stack;
	StackInit(&stack);
	while (pcur != NULL || !StackIsEmpty(&stack)){
		while (pcur !=NULL)
		{
			StackPush(&stack,pcur);
			pcur = pcur->pLeft;
		}
		Top = getFirst(&stack);
		StackPop(&stack);
		printf("%c ", Top->data);
		pcur = Top->pRight;
	}
}
//非递归后序
void PosOrder1(TreeNode *pTree){
	assert(pTree != NULL);
	Stack stack;
	StackInit(&stack);
	TreeNode *cur = pTree;
	TreeNode *top = NULL;
	TreeNode *last = NULL;
	while (cur != NULL || !StackIsEmpty(&stack))
	{
		while (cur!=NULL)
		{
			StackPush(&stack, cur);
			cur = cur->pLeft;
		}
		top = getFirst(&stack);
		if (top->pRight == NULL || top->pRight == last){
			printf("%c ", top->data);
			StackPop(&stack);
			last = top;
		}
		else
		{
			cur = top->pRight;
		}
	}
}
void test(){
	DataType *pinput = "ABD###CE##F";
	int index = 0;
	TreeNode *Tree = CreateTree(pinput, strlen(pinput), &index);
	PreOrder(Tree); printf("\n");
	InOrder(Tree); printf("\n");
	PostOrder(Tree); printf("\n");
	LevelOrder(Tree); printf("\n");
	PreOrder1(Tree); printf("\n");
	inOrder1(Tree); printf("\n");
	PosOrder1(Tree); printf("\n");
}

 

 

由于在非递归层序遍历以及判断一棵树是否为完全二叉树时用到了队列的相关操,这里给出队列的代码,便于读者理解:

 

 

#pragma once 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef void  * QDataType;

typedef struct QNode{
	QDataType data;
	struct QNode *pNext;//链式存储
}QNode;

typedef struct Queue{
	QNode *PFront;
	QNode *PRear;
	int size;
} Queue;

void QueueInit(Queue *pQ)
{
	assert(pQ != NULL);
	pQ ->PFront=pQ->PRear=NULL;
	pQ->size = 0;
}
//入队列
void QueuePush(Queue *pQ, QDataType data){
	assert(pQ != NULL);
	pQ->size++;
	QNode *pNewNode = (QNode*)malloc(sizeof(QNode));
	pNewNode->data = data;
	pNewNode->pNext = NULL;

	if (pQ->PRear == NULL){
		pQ->PFront = pQ->PRear = pNewNode;
		return;
	}
	pQ->PRear->pNext = pNewNode;
	pQ->PRear = pNewNode;
}
//出队列
void QueuePop(Queue *pQ){
	assert(pQ->PFront);
	assert(pQ->size > 0);
	pQ->size--;
	QNode *pOld = pQ->PFront;
	pQ->PFront = pQ->PFront->pNext;
	free(pOld);
	if (pQ->PFront == NULL){
		pQ->PRear = NULL;
	}
}
QDataType QueueFront(Queue *pQ){
	assert(pQ != NULL);
	assert(pQ->size > 0);
	return pQ->PFront->data;
}
int QueueIsEmpty(Queue *pQ)
{
	return pQ->size == 0 ? 1 : 0;
}
int QueueSize(Queue *pQ)
{
	return pQ->size;
}

 

在非递归前序、中序、后序遍历二叉树时用到了栈的相关操作,这里也一并给出:

 

 

#pragma once 

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef void  * QDataType;

typedef struct QNode{
	QDataType data;
	struct QNode *pNext;//链式存储
}QNode;

typedef struct Queue{
	QNode *PFront;
	QNode *PRear;
	int size;
} Queue;

void QueueInit(Queue *pQ)
{
	assert(pQ != NULL);
	pQ ->PFront=pQ->PRear=NULL;
	pQ->size = 0;
}
//入队列
void QueuePush(Queue *pQ, QDataType data){
	assert(pQ != NULL);
	pQ->size++;
	QNode *pNewNode = (QNode*)malloc(sizeof(QNode));
	pNewNode->data = data;
	pNewNode->pNext = NULL;

	if (pQ->PRear == NULL){
		pQ->PFront = pQ->PRear = pNewNode;
		return;
	}
	pQ->PRear->pNext = pNewNode;
	pQ->PRear = pNewNode;
}
//出队列
void QueuePop(Queue *pQ){
	assert(pQ->PFront);
	assert(pQ->size > 0);
	pQ->size--;
	QNode *pOld = pQ->PFront;
	pQ->PFront = pQ->PFront->pNext;
	free(pOld);
	if (pQ->PFront == NULL){
		pQ->PRear = NULL;
	}
}
QDataType QueueFront(Queue *pQ){
	assert(pQ != NULL);
	assert(pQ->size > 0);
	return pQ->PFront->data;
}
int QueueIsEmpty(Queue *pQ)
{
	return pQ->size == 0 ? 1 : 0;
}
int QueueSize(Queue *pQ)
{
	return pQ->size;
}

主函数直接使用test()用来测试:

 

#include "tree.h"
#include "Queue.h"

int main(){
	test();
	system("pause");
	return 0;
}

 

由于二叉树的相关操作比较多,也比较重要。在写代码时会出现纰漏,若有疑问欢迎随时指教,不胜感激。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值