二叉樹相關操作

   二叉树是使用的比较广泛的一种数据结构,二叉树的相关操作,包括初始化、新建、以及遍历。这里主要是为了学习二叉树的遍历算法,我总结后,写了八种二叉树的遍历算法,分别是:
  1.递归先序遍历
  2.递归中序遍历
  3.递归后序遍历
  4.非递归先序遍历(单栈辅助)
  5.非递归中序遍历(单栈辅助)
  6.非递归后序遍历(单栈辅助)
  7.递归层次遍历
  8.非递归层次遍历(队列辅助)
  当然,这里还要用到栈和队列,博客中以前有提到过(链式的栈和链式队列),其实还可以用顺序栈和顺序队列的(博客中后面将补上这块)。下面直接上代码:

LinkStack.h 链式栈头文件
#ifndef _LINK_STACK_H_H
#define _LINK_STACK_H_H

#include “BiTree.h”

typedef pBiTree LStackEle;

typedef struct LSNODE
{
LStackEle ele;
struct LSNODE *pnext;
}LSNode, *pLSNode;

typedef struct LSTACK
{
pLSNode top;
}LStack, *pLStack;

//栈初始化
void InitLinkStack(LStack &s);

//入栈
void PushLinkStack(LStack &s, LStackEle ele);

//出栈
void PopLinkStack(LStack &s, LStackEle &ele);

//判断栈是否为空
bool IsemptyLinkStack(LStack s);

//获得栈顶值
LStackEle GetTopLinkStack(LStack s);

#endif
LinkQueue.h 链式队列头文件
#ifndef _LINK_QUEUE_H_H
#define _LINK_QUEUE_H_H

#include “BiTree.h”

typedef pBiTree LQueueEle;

typedef struct LQNODE
{
LQueueEle ele;
struct LQNODE *pnext;
}LQNode, *pLQNode;

typedef struct LQUEUE
{
pLQNode rear;
pLQNode front;
}LQueue, *pLQueue;

//初始化队列
void InitLinkQueue(LQueue &q);

//入队
void EnLinkQueue(LQueue &q, LQueueEle ele);

//出队
void DeLinkQueue(LQueue &q, LQueueEle &ele);

//判断队列是否为空
bool IsemptyLinkQueue(LQueue q);

//获得队头元素值
LQueueEle GetFrontLinkQueue(LQueue q);

#endif

BiTree.h 二叉树头文件
#ifndef _BITREE_H_H
#define _BITREE_H_H

typedef struct BINODE
{
int ele;
struct BINODE *plchild;
struct BINODE *prchild;
}BiNode, *pBiTree;

//初始化二叉树(含根节点)
void InitBiTree(pBiTree &bt, int ele);

//创建二叉树节点
BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele);

//插入左子二叉树
void InsertLChild(pBiTree parent, pBiTree lchild);

//插入右子二叉树
void InsertRChild(pBiTree parent, pBiTree rchild);

//计算二叉树的深度
int DeepBiTree(pBiTree bt);

//递归先序遍历
void RePreOrderTraverse(pBiTree bt);

//递归中序遍历
void ReInOrderTraverse(pBiTree bt);

//递归后序遍历
void RePostOrderTraverse(pBiTree bt);

//非递归先序遍历二
void NonRePreOrderTraverse(pBiTree bt);

//非递归中序遍历
void NonReInOrderTraverse(pBiTree bt);

//非递归后序遍历
void NonRePostOrderTraverse(pBiTree bt);

//非递归层次遍历
void NonReLevelOrderTraverse(pBiTree bt);

//递归层次遍历
void ReLevelOrderTraverse(pBiTree bt);

void PrintLevelNode(pBiTree bt, int level);

#endif

LinkStack.cpp 链式栈源文件
#include “LinkStack.h”
#include <stdlib.h>
#include <stdio.h>

//栈初始化
void InitLinkStack(LStack &s)
{
s.top= NULL;
}

//入栈
void PushLinkStack(LStack &s, LStackEle ele)
{
pLSNode pnew = (pLSNode)malloc(sizeof(LSNode));
if (pnew == NULL)
{
printf(“内存分配失败!\n”);
exit(EXIT_FAILURE);
}

pnew->ele = ele;
pnew->pnext = s.top;
s.top = pnew;

}

//出栈
void PopLinkStack(LStack &s, LStackEle &ele)
{
pLSNode pt = NULL;
if (IsemptyLinkStack(s))
{
printf(“栈为空,不能出栈操作!\n”);
exit(EXIT_FAILURE);
}
else
{
ele = s.top->ele;
pt = s.top;
s.top = pt->pnext;
free(pt);
pt = NULL;
}

}

//判断栈是否为空
bool IsemptyLinkStack(LStack s)
{
if (s.top == NULL)
return true;
else
return false;
}

//获得栈顶元素
LStackEle GetTop(LStack s)
{
if (IsemptyLinkStack(s))
{
printf(“栈为空,不能获得栈顶元素值!\n”);
exit(EXIT_FAILURE);
}
else
return s.top->ele;
}
LinkQueue.cpp 链式队列源文件
#include <stdlib.h>
#include <stdio.h>
#include “LinkQueue.h”

//初始化队列
void InitLinkQueue(LQueue &q)
{
q.front = (pLQNode)malloc(sizeof(LQNode));
if (q.front == NULL)
{
printf(“内存分配失败!\n”);
exit(EXIT_FAILURE);
}

q.rear = q.front;

}

//入队
void EnLinkQueue(LQueue &q, LQueueEle ele)
{
pLQNode pnew = (pLQNode)malloc(sizeof(LQNODE));
if (pnew == NULL)
{
printf(“内存分配失败!\n”);
exit(EXIT_FAILURE);
}

pnew->ele = ele;
pnew->pnext = NULL;
q.rear->pnext = pnew;
q.rear = pnew;

}

//出队
void DeLinkQueue(LQueue &q, LQueueEle &ele)
{
pLQNode pt = NULL;

if (IsemptyLinkQueue(q))
{
	printf("队列为空,不能出队操作!\n");
	exit(EXIT_FAILURE);
}

ele = q.front->pnext->ele;
pt = q.front->pnext;
q.front->pnext = pt->pnext;
free(pt);

/*
pt是最后一个节点时,释放完了以后,尾指针指向的
是随机内存,所以让它和头指针指向同一个地址。
*/
if (q.front->pnext == NULL)
q.rear = q.front;
}

//判断队列是否为空
bool IsemptyLinkQueue(LQueue q)
{
if (q.front == q.rear)
return true;
else
return false;
}

//获得队头元素
LQueueEle GetFrontLinkQueue(LQueue q)
{
if (IsemptyLinkQueue(q))
{
printf(“队列为空,不能获得队头元素!\n”);
exit(EXIT_FAILURE);
}

return q.front->pnext->ele;

}

BiTree.cpp 二叉树源文件
#include <stdlib.h>
#include <stdio.h>
#include “BiTree.h”
#include “LinkStack.h”
#include “LinkQueue.h”

//初始化二叉树(含根节点)
void InitBiTree(pBiTree &bt, int ele)
{
bt = (BiNode *)malloc(sizeof(BiNode));
if (bt == NULL)
{
printf(“内存分配失败!\n”);
exit(EXIT_FAILURE);
}

bt->ele = ele;
bt->plchild = NULL;
bt->prchild = NULL;

}

//创建二叉树节点
BiNode *CreateBiTreeNode(pBiTree lchild, pBiTree rchild, int ele)
{
BiNode *pnew = (BiNode *)malloc(sizeof(BiNode));
if (pnew == NULL)
{
printf(“内存分配失败!\n”);
exit(EXIT_FAILURE);
}

pnew->ele = ele;
pnew->plchild = lchild;
pnew->prchild = rchild;

return pnew;

}

//插入左子二叉树
void InsertLChild(pBiTree parent, pBiTree lchild)
{
parent->plchild = lchild;
}

//插入右子二叉树
void InsertRChild(pBiTree parent, pBiTree rchild)
{
parent->prchild = rchild;
}

//用递归的方法计算二叉树的深度
int DeepBiTree(pBiTree bt)
{
int ldeep = 0, rdeep = 0;

if (bt)
{
	ldeep = DeepBiTree(bt->plchild);
	rdeep = DeepBiTree(bt->prchild);
	return (ldeep > rdeep ? ldeep : rdeep) + 1;
}
else
	return 0;

}

//(一)递归先序遍历
void RePreOrderTraverse(pBiTree bt)
{
if(bt != NULL)
{
printf("%d ", bt->ele);
RePreOrderTraverse(bt->plchild);
RePreOrderTraverse(bt->prchild);
}
}

//(二)递归中序遍历
void ReInOrderTraverse(pBiTree bt)
{
if(bt != NULL)
{
ReInOrderTraverse(bt->plchild);
printf("%d ", bt->ele);
ReInOrderTraverse(bt->prchild);
}
}

//(三)递归后序遍历
void RePostOrderTraverse(pBiTree bt)
{
if(bt != NULL)
{
RePostOrderTraverse(bt->plchild);
RePostOrderTraverse(bt->prchild);
printf("%d ", bt->ele);
}
}

//(四)非递归先序遍历
void NonRePreOrderTraverse(pBiTree bt)
{
LStack s;
InitLinkStack(s);

while (bt != NULL || !IsemptyLinkStack(s))
{
	while ( bt != NULL)
	{
		printf("%d ", bt->ele);
		PushLinkStack(s, bt);
		bt = bt->plchild;
	}

	if (!IsemptyLinkStack(s))
	{
		PopLinkStack(s, bt);
		bt = bt->prchild;
	}
}

}

//(五)非递归中序遍历
void NonReInOrderTraverse(pBiTree bt)
{
LStack s;
InitLinkStack(s);

while (bt != NULL || !IsemptyLinkStack(s))
{
	while (bt != NULL)
	{
		PushLinkStack(s, bt);
		bt = bt->plchild;
	}

	if (!IsemptyLinkStack(s))
	{
		PopLinkStack(s, bt);
		printf("%d ", bt->ele);
		bt = bt->prchild;
	}
}

}

//(六)非递归后序遍历
void NonRePostOrderTraverse(pBiTree bt)
{
LStack s;
InitLinkStack(s);
BiNode * pt = NULL;

while (bt != NULL || !IsemptyLinkStack(s))
{
	while (bt != NULL)
	{
		PushLinkStack(s, bt);
		bt = bt->plchild;
	}

	if (!IsemptyLinkStack(s))
	{
		PopLinkStack(s, bt);

		if (bt->prchild == NULL || bt->prchild == pt)
		{
			printf("%d ", bt->ele);
			pt = bt;
			bt = NULL;
		}
		else
		{
			PushLinkStack(s, bt);
			bt = bt->prchild;
		}
	}
}

}

//(七)非递归层次遍历
void NonReLevelOrderTraverse(pBiTree bt)
{
LQueue q;
InitLinkQueue(q);
BiNode *pt = NULL;

if (bt != NULL)
{
	EnLinkQueue(q, bt);

	while (!IsemptyLinkQueue(q))
	{
		DeLinkQueue(q, pt);
		printf("%d ", pt->ele);
		if (pt->plchild != NULL)
			EnLinkQueue(q, pt->plchild);
		if (pt->prchild != NULL)
			EnLinkQueue(q, pt->prchild);
	}
}

}

//(八)递归层级遍历
void ReLevelOrderTraverse(pBiTree bt)
{
int i, deep;

if (bt != NULL)
{
	deep = DeepBiTree(bt);
	for(i=1; i<deep+1; i++)
		PrintLevelNode(bt, i);
}

}

void PrintLevelNode(pBiTree bt, int level)
{
if (bt != NULL && level > 0)
{
if (level == 1)
printf("%d ", bt->ele);
PrintLevelNode(bt->plchild, level - 1);
PrintLevelNode(bt->prchild, level - 1);
}
}

main.cpp 测试程序源文件
#include <stdio.h>
#include “BiTree.h”
#include “LinkStack.h”
#include “LinkQueue.h”

int main(void)
{
//二叉树测试代码
pBiTree bt;
InitBiTree(bt, 10);

pBiTree lchild = CreateBiTreeNode(CreateBiTreeNode(NULL, 
	CreateBiTreeNode(CreateBiTreeNode(NULL, NULL, 80), 
	NULL, 55), 40), NULL, 20);
InsertLChild(bt, lchild);

pBiTree rchild = CreateBiTreeNode(NULL, CreateBiTreeNode(
	CreateBiTreeNode(NULL, NULL, 60), 
	CreateBiTreeNode(NULL, NULL, 70), 50), 30);
InsertRChild(bt, rchild);

printf("********二叉树图形********\n");
printf("          10\n");
printf("         /  \\\n");
printf("        20   30\n");
printf("       / \\  / \\\n");
printf("     40   N N  50\n");
printf("    / \\       /  \\\n");
printf("   N  55     60   70\n");
printf("     / \\    / \\  / \\\n");
printf("   80   N  N  N  N  N\n");
printf("  / \\\n");
printf(" N   N\n");

printf("二叉树的深度:%d", DeepBiTree(bt));

printf("\n**********************************");

printf("\n递归前序遍历:");
RePreOrderTraverse(bt);
printf("\n递归中序遍历:");
ReInOrderTraverse(bt);
printf("\n递归后序遍历:");
RePostOrderTraverse(bt);

printf("\n**********************************");

printf("\n非递归前序遍历:");
NonRePreOrderTraverse(bt);
printf("\n非递归中序遍历:");
NonReInOrderTraverse(bt);
printf("\n非递归后序遍历:");
NonRePostOrderTraverse(bt);

printf("\n**********************************");

printf("\n非递归层次遍历:");
NonReLevelOrderTraverse(bt);
printf("\n递归层次遍历:");
ReLevelOrderTraverse(bt);
putchar('\n');
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值