使用递归遍与历释放二叉数

// 使用递归遍与历释放二叉数

#include "stdafx.h"
#include <stdio.h>
#include <stdlib.h>

struct Node
{
	int data;
	Node *pLeft;
	Node *pRight;
};

void InsertTree(Node *&pRoot,int data)
{
	if(pRoot == NULL){
		pRoot=(Node *)malloc(sizeof(Node));
		pRoot->data=data;
		pRoot->pLeft=pRoot->pRight=NULL;
		return;
	}
	if(pRoot->data<data)
		InsertTree(pRoot->pRight,data);
	else
		InsertTree(pRoot->pLeft,data);
}

void PrintTree(const Node *pRoot)
{
	if(pRoot == NULL)
		return;
	PrintTree(pRoot->pLeft);
	printf("node:%d\n",pRoot->data);
	PrintTree(pRoot->pRight);
}

void FreeTree(Node *pRoot)
{
	if(pRoot == NULL)
		return;
	FreeTree(pRoot->pLeft);
	FreeTree(pRoot->pRight);
	printf("free:%d\n",pRoot->data);
	free(pRoot);
}

int main()
{
	Node *pRoot=NULL;

	InsertTree(pRoot,5);
	InsertTree(pRoot,8);
	InsertTree(pRoot,3);
	InsertTree(pRoot,4);
	InsertTree(pRoot,2);

	PrintTree(pRoot);
	FreeTree(pRoot);
	return 0;
}


 

1.问题描述 设有二叉树如图1.7.1所示: 图1.7.1 二叉树 编程实现有关二叉树的下列运算: (1)创建一棵二叉树; (2)采用递归方法分别实现对上述二叉树的先序、中序、后序,输出序列; (3)采用链栈的迭代方法分别实现对上述二叉树的先序、中序、后序,输出序列; (4)利用队列实现二叉树的层序。 2.基本要求 (1)分别设计二叉树、链栈结点、链队列结点据结构; (2)在参考程序中的下划线处填入适当的语句,完善参考程序; (3)理解并掌握二叉树的各种算法; (4)上机调试、测试参考程序,打印测试结果,对结果进行分析。 3.据结构设计 (1)二叉树结点据结构 typedef struct BiTNode { // 定义树结束结构 char data; // 假定树的元素类型为int struct BiTNode *lchild; // 左子树 struct BiTNode *rchild; // 右子树 } BiTNode,*BiTree; (2)链栈结点据结构(用于二叉树递归迭代) typedef struct Stack{ // 定义链栈结点结构 BiTNode *t; // 栈结点元素为指向二叉树结点的指针 int flag; // 后序时用到该标志 struct Stack *next; // 栈结点链指针 } Stack, *LinkStack; (3)链队列据结构(用于二叉树的层序) typedef struct QNode{ // 定义链队列结点结构 BiTree t; // 链队列结点据域 struct QNode *next; // 链队列结点指针域 }QNode, *QueuePtr; typedef struct { // 队列类型 QueuePtr front; // 队首指针 QueuePtr rear; // 队尾指针 }LinkQueue; 4.算法设计 (1)二叉树、链栈的基本操作、链队列的基本操作算法设计 // ① 进栈函 void Push(LinkStack &top, BiTree tree) { // 树结点入栈 LinkStack p; // 工作指针 p=(Stack *)malloc(sizeof(Stack)); // 申请栈结点 p->t = tree; // 根结点进栈 p->next = top; // 新栈结点指向栈顶 top = p; // 栈顶为新结点 } // ② 出栈函 void Pop(LinkStack &top, BiTree &tree) // 出栈,栈内元素赋值给树结点 { LinkStack p=top; // 工作指针 if(top == NULL) // 空栈 tree = NULL; else { // 栈非空 tree=top->t; // 栈顶结点元素赋值给树结点 top = top->next; // 栈顶指向下一个链接,完成出栈 free(p); // 释放栈顶结点空间 } } // ③ 初始化链队列函 Status InitQueue(LinkQueue &Q) { // 创建一个带附加表头结点的空链队列Q Q.front= Q.rear = (QueuePtr)malloc(sizeof(QNode)); if(!Q.front) return ERROR; Q.front->next = NULL; return OK; } // ④ 进队函 Status EnQueue(LinkQueue &Q, BiTree e) { //将元素e插入到带头结点的链队列Q中 QueuePtr p; p=(QueuePtr)malloc(sizeof(QNode)); if(!p) return ERROR; p->t = e; p->next=NULL; Q.rear->next = p; Q.rear=p; return OK; } // ⑤ 出队函 Status DeQueue(LinkQueue &Q, BiTree &e) { //若队列不空,则队首元素出队列,用e返回其值,返回OK,否则返回ERROR QueuePtr p; if(Q.rear==Q.front) return ERROR; p=Q.front->next; e=p->t; Q.front->next=p->next; if(Q.rear==p) Q.rear=Q.front; free(p); return OK; } // ⑥先序递归方法 void re_PreOrder(BiTNode *tree) { if(tree!=NULL) { // 不为空子树时递归 printf("%c ",tree->data); // 访问根结点 re_PreOrder (tree->lchild); // 先序左子树 re_PreOrder (tree->rchild); // 先序右子树 } } // ⑦中序递归方法 void re_MidOrder(BiTNode *tree) { // 请编写中序子程序 1 } // ⑧后序递归方法 void re_PostOrder(BiTNode *tree) { if(tree!=NULL) { // 不为空子树时递归 re_PostOrder (tree->lchild); // 先后序左子树 re_PostOrder (tree->rchild); // 再后序右子树 printf("%c ",tree->data); // 最后访问根结点 } } // ⑨先序,采用链栈的迭代方法 void st_PreOrder(BiTNode *tree) { LinkStack top; // 栈顶指针 top=NULL; // 初始化为空栈 while(tree!=NULL) { // 二叉树还未完 2 ; // 访问根结点 if( 3 ) // 右子树结点入栈 Push(top, tree->rchild); if(tree->lchild!=NULL) // 左子树结点入栈 4 ; Pop(top, tree); // 树结点出栈 } } // ⑩中序,采用链栈的迭代方法 void st_MidOrder(BiTNode *tree) { LinkStack top; // 栈顶指针 top = NULL; // 初始化为空栈 while( 5 ){ // 循环条件为二叉树还未完,或栈非空 while(tree!=NULL) { // 二叉树还未完 Push(top, tree); // 树结点入栈 6 ; // 沿左子树前进,将经过的结点依次进栈 } if(top!=NULL){ // 左子树点入栈结束,且栈非空 Pop(top, tree); // 树结点出栈 7 ; // 访问根结点 8 ; // 向右子树前进 } } } // ○11后序,采用链接栈的送代方法 void st_PostOrder(BiTNode *tree) { LinkStack top; // 栈顶指针 top=NULL; // 初始化为空栈 do { while( 9 ) { // 二叉树还未完 Push(top, tree); // 树结点人栈 top->flag = 0; // 标志为0,表示右子树未访问。 10 ; // 沿左子树前进,将经过的结点依次进栈 } if(top!=NULL) { // 栈非空 while(top!=NULL&& 11 ){ // 右子树已访问 Pop(top, tree); // 出栈 printf("%c ", tree->data); } if(top!=NULL) { 12 ; // 置右子树为访问标志 tree = (top->t)->rchild; // 查找栈顶无素的右子树 } } } while(top!=NULL); // 循环条件为栈非空 } // ○12二叉树的层序 void LevelOrder(BiTNode *root) { LinkQueue Q; BiTree p; if (root !=NULL) { InitQueue(Q); EnQueue(Q,root); while( 13 ) { // 循环条件为队非空 DeQueue(Q,p); printf("%c ", p->data); if(p->lchild!=NULL) EnQueue(Q, p->lchild); if(p->rchild!=NULL) EnQueue(Q, p->rchild); } //While printf("\n"); } //if } //LevelOrder // ○13创建二叉树 void CreateBiTree(BiTree &T) { // 先序递归方式创建一棵二叉树 char ch; scanf("\n%c",&ch); // 输入根结点的值 if (ch =='#') // 终止项 T = NULL; else { T = (BiTree)malloc(sizeof(BiTNode)); // 创建根结点 if (!T) exit(-1); T->data = ch; printf("\n请输入%c结点的左子结点(#表无):",T->data ); // 先序创建左子树 CreateBiTree(T->lchild); printf("\n请输入%c结点的右子结点(#表无):",T->data ); // 先序创建右子树 CreateBiTree(T->rchild); } } //○14以括号表示格式输出二叉树 void OutputBiTree(BiTree T) { // 先序递归方式输出括号表示的二叉树 if(T!=NULL) // 终止项 { printf("%c", T->data); // 访问根结点 if(T->lchild!=NULL||T->rchild!=NULL) { printf("("); // 根的孩子用圆括号对括 OutputBiTree(T->lchild); // 先序输出左子树 if(T->rchild!=NULL) printf(","); // 根的左右孩子以“,”分隔 OutputBiTree(T->rchild); // 先序输出右子树 printf(")"); // 根的孩子用圆括号对括 } } } (2).主函。 // 本程序实现了二叉查找树的先序,中序,后序递归和迭代方法。 void main() { BiTNode *proot; // 定义树 proot=NULL; // 初始化为空树 printf("请输入根结点元素(#表无):"); 14 ; // 创建二叉树 printf("\n(1)二叉树创建成功,其括号表示格式输出:\n\t"); OutputBiTree(proot); printf("\n(2)先序递归方法\n\t"); 15 ; // 先序递归方法 printf("(3)中序递归方法\n\t"); 16 ; // 中序递归方法 printf("(4)后序递归方法\n\t"); 17 ; // 后序递归方法 printf("(5)先序,链接栈的迭代方法\n\t"); 18 ; // 先序,采用链接栈的迭代方法 printf("(6)中序,链接栈的迭代方法\n\t"); 19 ; // 中序,采用链接栈的迭代方法 printf("(7)后序,链接栈的迭代方法\n\t"); 20 ; // 后序,采用链接栈的迭代方法 printf("(8)层序,链队列的迭代方法\n\t"); LevelOrder( proot ); // 后序,采用链接栈的迭代方法 }
11-14
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值