【数据结构-H】链式二叉树

目录:

  1. 分析顺序存储二叉树的优缺点
  2. 使用孩子法实现二叉树

1.二叉树的顺序结构

普通的二叉树不适合用数组来存储,因为可能会造成大量的空间浪费。而完全二叉树更适合利用顺序结构存储。现实中我们通常把堆(一种二叉树)使用顺序结构的数组来存储,需要注意的是这里的堆操作和操作系统虚拟进程地址空间是两回事,一个是数据结构,一个是操作系统中管理内存的一块区域分段。

2.下面我们来看孩子法实现二叉树程序:

头文件BinTree.h代码如下:

#pragma once

//二叉树的链式存储方式--孩子表示法
typedef int BTDataType;

typedef struct BTNode{
	struct BTNode* _pLeft;
	struct BTNode* _pRight;
	BTDataType _data;
}BTNode;

//获取二叉树
BTNode* BuyBinTreeNode(BTDataType data);

//二叉树的创建
BTNode* _CreatBinTree(BTDataType* array, int size, int* index, BTDataType invalid);

//重新包装
BTNode* CreatBinTree(BTDataType* array, int size, BTDataType invalid);

//二叉树的拷贝(查询概念)
void* CopyBinTree(BTNode* pRoot);

//前序遍历
void PreOrder(BTNode* pRoot);

//中序遍历
void InOrder(BTNode* pRoot);

//后序遍历
void PosOrder(BTNode* pRoot);

//获取二叉树中第k层结点的个数
void GetKLevelNodeCount(BTNode* pRoot, int K);

//获取二叉树中的结点
int GetBinTreeSize(BTNode* pRoot);

//叶子结点个数
int GetLeafCount(BTNode* pRoot);

//获取树的高度
void GetBinTreeHeight(BTNode* pRoot);

//元素在树中位置的查找
BTNode BinTreeFind(BTNode* pRoot, BTDataType x);

//销毁
void DestroyBinTree(BTNode** pRoot);
//测试
void TestBinTree();

源文件BinTree.c代码如下:

#include "BinTree.h"
#include <stdio.h>
#include <malloc.h>
#include <assert.h>
#include <string.h>

//获取二叉树
BTNode* BuyBinTreeNode(BTDataType data){
	BTNode* pNewNode = (BTNode*)malloc(sizeof(BTNode));
	if (NULL == pNewNode){
		assert(0);
		return NULL;
	}
	pNewNode->_data = data;
	pNewNode->_pLeft = NULL;
	pNewNode->_pRight = NULL;
	return pNewNode;
}

//二叉树的创建
BTNode* _CreatBinTree(BTDataType* array, int size, int* index, BTDataType invalid){
	BTNode* pRoot = NULL;
	if (*index < size && invalid != array[*index]){
		//创建根节点
		pRoot = BuyBinTreeNode(array[*index]);

		//创建根的左子树
		++(*index);
		pRoot->_pLeft = _CreatBinTree(array, size, index, invalid);

		//创建根的右子树
		++(*index);
		pRoot->_pRight = _CreatBinTree(array, size, index, invalid);
	}
	return pRoot;
}

//重新包装
BTNode* CreatBinTree(BTDataType* array, int size,BTDataType invalid){
	int index = 0;
	return _CreatBinTree(array, size, &index, invalid);
}

//前序遍历
void PreOrder(BTNode* pRoot){
	if (pRoot){
		printf("%c ", pRoot->_data);
		PreOrder(pRoot->_pLeft);
		PreOrder(pRoot->_pRight);
	}
}

//中序遍历
void InOrder(BTNode* pRoot){
	if (pRoot){
		InOrder(pRoot->_pLeft);
		printf("%c ", pRoot->_data);
		InOrder(pRoot->_pRight);
	}
}

//后序遍历
void PosOrder(BTNode* pRoot){
	if (pRoot){
		PosOrder(pRoot->_pLeft);
		PosOrder(pRoot->_pRight);
		printf("%c ", pRoot->_data);
	}
}

//叶子结点个数
int GetLeafCount(BTNode* pRoot){
	if (NULL == pRoot){
		return 0;
	}
	if (NULL == pRoot->_pLeft && NULL == pRoot->_pRight){
		return 1;
	}
	return GetLeafCount(pRoot->_pLeft) + GetLeafCount(pRoot->_pRight);
}

//销毁(后序方法)
void DestroyBinTree(BTNode** pRoot){
	if (*pRoot){
		DestroyBinTree(&(*pRoot)->_pLeft);
		DestroyBinTree(&(*pRoot)->_pRight);
		free(*pRoot);
		*pRoot = NULL;
	}
}

//测试
void TestBinTree(){
	char* str = "ABCDE#F##G#";
	BTNode* pRoot = CreatBinTree(str, strlen(str),'#');
	printf("前序遍历结果: ");
	PreOrder(pRoot);
	printf("\n");

	printf("中序遍历结果: ");
	InOrder(pRoot);
	printf("\n");
	
	printf("后序遍历结果: ");
	PosOrder(pRoot);
	printf("\n");
	DestroyBinTree(&pRoot);
}

测试代码:

#include "BinTree.h"

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

 

 

 

 

 

 

~bye~ 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值