17黑马笔记之二叉树的拷贝与释放

17黑马笔记之二叉树的拷贝与释放

1 二叉树的拷贝思想: 先传进二叉树的根节点,然后先遍历其左子树,令其执行到左子树的最后节点;再遍历其右子树,递归遍历左右子树都要接收返回值(malloc出的新节点地址)。然后malloc创建新的节点并赋值,返回新的节点便可。递归条件:传进的节点不为空(绝大多数都是这个)。

2 二叉树的释放: 同样的,先遍历左子树,使其先执行左子树的最后一个节点,再遍历右子树。然后释放该节点内存便可。递归条件:传进的节点不为空。

3 代码实现:

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

//定义二叉树节点
typedef struct BINARYNODE{
	char ch;
	struct BINARYNODE *lchild;  
	struct BINARYNODE *rchild;  
}BinaryNode;

//拷贝二叉树 ok 懂了
BinaryNode *CopyBinaryTree(BinaryNode *root){

	if(root==NULL){
		return NULL;
	}

	//先拷贝左子树
	BinaryNode *lchild=CopyBinaryTree(root->lchild);
	//再拷贝右子树
	BinaryNode *rchild=CopyBinaryTree(root->rchild);

	//最后依次拷贝每个节点
	BinaryNode *newnode=(BinaryNode*)malloc(sizeof(BinaryNode));
	newnode->ch=root->ch;
	newnode->lchild=lchild; //这里出错了!!!,而且不能用root->lchild的原因是:不能使堆开辟
	newnode->rchild=rchild;//出来的newnode->lchild指向栈开辟的内容,否则当指向完释放内存后,newnode->lchild
	                       //所指的栈内容也释放,结果CreateBinartTree函数结束在释放一次就会类似浅拷贝问题
	return newnode;        //所以必须要用返回值赋值(画图就可以了)
}

//遍历二叉树  ok 懂了
void RecursionBinaryTree(BinaryNode *root){

	if(root==NULL){
		return ;
	}
	//前序遍历 --根左右
	printf("%c",root->ch);
	RecursionBinaryTree(root->lchild);
	RecursionBinaryTree(root->rchild);

	return ;
}

//释放二叉树 ok
void DestroyBinaryTree(BinaryNode *root){

	if(root==NULL){
		return ;
	}
	//free(root);  //我写的没问题,用他的出错了--但是只是free了一个根节点啊,所以这个是不对的

	//他写的--实际上这种释放可以说是后序释放
	//先释放左子树
	DestroyBinaryTree(root->lchild);
	//右子树
	DestroyBinaryTree(root->rchild);
	//释放当前根节点
	free(root);

	return ;
}

void CreateBinartTree(){

	//创建数据节点
	BinaryNode node1={'A',NULL,NULL};
	BinaryNode node2={'B',NULL,NULL};
	BinaryNode node3={'C',NULL,NULL};
	BinaryNode node4={'D',NULL,NULL};
	BinaryNode node5={'E',NULL,NULL};
	BinaryNode node6={'F',NULL,NULL};
	BinaryNode node7={'G',NULL,NULL};
	BinaryNode node8={'H',NULL,NULL};

	//建立节点关系 A-F-G-H
	//              \B
	//               \C-E
	//                \D
	node1.lchild=&node2;
	node1.rchild=&node6;
	node2.rchild=&node3;
	node3.lchild=&node4;
	node3.rchild=&node5;
	node6.rchild=&node7;
	node7.rchild=&node8;

	//拷贝二叉树
	BinaryNode *root=CopyBinaryTree(&node1);

	//遍历二叉树
	RecursionBinaryTree(root);
	
	//释放二叉树
	DestroyBinaryTree(root);

}

int main(){

	CreateBinartTree();

	return 0;
}


//总结:这个项目有问题再释放内存那里,但是我分析过了代码应该没有问题才对啊!!!
//懂了,在拷贝时出问题!不能用原来的树的内容给他指向,导致两个二叉树的两个指针指向同一片区域,
//必须新建变量给他新的指向
发布了54 篇原创文章 · 获赞 1 · 访问量 699

猜你喜欢

转载自blog.csdn.net/weixin_44517656/article/details/105600839
今日推荐