数据结构-二叉树链式结构的实现

二叉树链式结构的遍历

所谓遍历即沿着某条搜索路线,依次对树中每个结点均做一次且做一次访问。访问结点所做的操作依赖于具体的应用问题。遍历是二叉树上最重要的运算之一,是二叉树上进行其他运算之基础。
前序/中序/后序的递归结构遍历:是根据访问节点操作发生未知明明

  1. NLR:前序遍历:访问根节点的操作发生在遍历其左右子树之前
  2. LNR:中序遍历:访问根节点的操作发生在遍历其左右子树之间
  3. LRN:后序遍历:访问根节点的操作发生在遍历其左右子树之后
typedef char DataType;

typedef struct BNode
{
	DataType _data;
	struct BNode* _left;
	struct BNode* _right;
}BNode;

//ABD##E#H##CF##G##
BNode* creatBtree(DataType arr[], int* idx)
{
	if (arr[*idx] == '#')
	{
		(*idx)++;
		return NULL;
	}
	else
	{
		//创建以当前数据为根的子树
		BNode* root = (BNode*)malloc(sizeof(BNode));
		root->_data = arr[*idx];
		++(*idx);

		root->_left = creatBtree(arr, idx);
		root->_right = creatBtree(arr, idx);
		return root;
	}
}
//前序
void preOrder(BNode* root)
{
	//根 左子树 右子树
	if (root)
	{
		printf("%c", root->_data);
		preOrder(root->_left);
		preOrder(root->_right);
	}
}
//中序
void inOrder(BNode* root)
{
	//左子树 根 右子树
	if (root)
	{
		inOrder(root->_left);
		printf("%c", root->_data);
		inOrder(root->_right);
	}
}
//后序
void postOrder(BNode* root)
{
	//左子树 右子树 根
	if (root)
	{
		postOrder(root->_left);
		postOrder(root->_right);
		printf("%c", root->_data);
	}
}

int bTreeSize1(BNode* root)
{
	if (root == NULL)
		return 0;
	//root左子树的结点 + root右子树的结点 + 1
	return bTreeSize1(root->_left) + bTreeSize1(root->_right) + 1;
}

//写法2
void bTreeSize2(BNode* root, int* idx)
{
	if (root)
	{
		++(*idx);
		bTreeSize2(root->_left, idx);
		bTreeSize2(root->_right, idx);
	}
}

int bTreeLeafSize(BNode* root)
{
	if (root == NULL)
		return 0;
	else if (root->_left == NULL && root->_right == NULL)
		return 1;
	//左右子树的叶子
	return bTreeLeafSize(root->_left) + bTreeLeafSize(root->_right);
}

int bTreeKSize(BNode* root, int k)
{
	if (root == NULL)
		return 0;
	if (k == 1)
		return 1;
	//左右子树第K - 1层结点和
	return bTreeKSize(root->_left, k - 1) + bTreeKSize(root->_right, k - 1);
}

BNode* bTreeFind(BNode* root, DataType ch)
{
	BNode* node;
	if (root == NULL)
		return NULL;
	if (root->_data == ch)
		return root;
	//左子树
	node = bTreeFind(root->_left, ch);
	if (node)
		return node;
	//右子树
	return bTreeFind(root->_right, ch);
}

//层序遍历(借助之前的队列代码接口)
//void bTreeLevelOrder(BNode* root)
//{
//	//借助队列保存节点
//	Queue q;
//	initQueue(&q);
//	//根节点存入队列
//	if (root)
//		queuePush(&q, root);
//	//遍历队列中的每一个节点
//	while (!queueEmpty(&q))
//	{
//		//获取队头元素
//		Node* front = queueFront(&q);
//		//出队
//		queuePop(&q);
//
//		printf("%d", front->_data);
//		//保存队头元素的左右孩子节点
//		if (front->_left)
//			queuePush(&q, front->_left);
//		if (front->_right)
//			queuePush(&q, front->_right);
//	}
//	printf("\n");
//}

void bTreeDestroy(BNode** root)
{
	bTreeDestroy(&((*root)->_left));
	bTreeDestroy(&((*root)->_right));
	free(*root);
	*root = NULL;
}

//完全二叉树:层序遍历,节点连续,中间没有空节点
//int isCompleteBtree(Node* root)
//{
//	Queue q;
//	initQueue(&q);
//	if (root)
//		queuePush(&q, root);
//	//遍历队列中的每一个节点
//	while (!queueEmpty(&q))
//	{
//		//获取队头元素
//		Node* front = queueFront(&q);
//		//出队
//		queuePop(&q);
//		if (front)
//		{
//			queuePush(&q, front->_left);
//			queuePush(&q, front->_right);
//		}
//		else
//			break;
//	}
//	//查看剩余元素中,是否有非空节点
//	while (!queueEmpty(&q))
//	{
//		Node* front = queueFront(&q);
//		queuePop(&q);
//		if (front)
//			//如果剩余元素中存在非空节点,说明节点不连续
//			return 0;
//	}
//	//所有的非空节点都是连续的
//	return 1;
//}

void test()
{
	char arr[] = "ABD##E#H##CF##G##";
	int idx = 0;
	BNode* root = creatBtree(arr, &idx);
	preOrder(root);
	printf("\n");
	inOrder(root);
	printf("\n");
	postOrder(root);
	printf("\n");
	printf("size: %d \n", bTreeSize1(root));

	int count = 0;
	bTreeSize2(root, &count);
	printf("size: %d \n", count);

	printf("Ksize: k-->%d: %d\n", 4, bTreeKSize(root, 4));

	BNode* node = bTreeFind(root, 'G');
	printf("%p-->%c\n", node, *node);
	bTreeDestroy(&root);
}



int main()
{
	test();
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值