链式队列实现树的层序遍历

前言:链式队列实现树的层序遍历的笔记

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAXSIZE 100
#define OK 1
#define ERROR 0

// dim something struct for writting tree's struct;
// travel tree via / pre order travel / in order travel / post order travel
// 代码实现
// 链式层序插入
// 链式层序输出结点

typedef int ElemType;
typedef int Status;
// 树相关结点的定义
typedef struct _TreeNode{
	ElemType nodeData;
	struct _TreeNode* pLeftTree;
	struct _TreeNode* pRightTree;
}TreeNode, *PTreeNode;
typedef struct _SqTree{
	TreeNode* pRootTreeNode;
	int iTreeSize;
}SqTree, *PSqTree;

// 链队列用于层次结点遍历
typedef struct _LinkNode{
	TreeNode* pTreeNode;
	struct _LinkNode* nextLinkNode;
}LinkNode, *PLinkNode;
typedef struct _LinkQueue{
	LinkNode* pHeadLinkNode;
}LinkQueue, *PLinkQueue;

// 初始化链队列
Status initLinkQueue(LinkQueue* pLinkQueue)
{
	if (pLinkQueue->pHeadLinkNode != NULL)
		return ERROR;
	// 正常初始化
	pLinkQueue->pHeadLinkNode = malloc(sizeof(LinkNode));
	memset(pLinkQueue->pHeadLinkNode, 0, sizeof(LinkNode));
	return OK;
}

// 队列先进先出
Status push(LinkQueue* pLinkQueue, TreeNode* pTreeNode)
{
	LinkNode* pLinkNode = NULL;
	LinkNode* pTempLinkNode = NULL;
	if (pLinkQueue->pHeadLinkNode == NULL)
		return ERROR;
	pTempLinkNode = pLinkQueue->pHeadLinkNode;
	while (pTempLinkNode->nextLinkNode != NULL)
		pTempLinkNode = pTempLinkNode->nextLinkNode;
	pLinkNode = malloc(sizeof(LinkNode));
	memset(pLinkNode, 0, sizeof(LinkNode));
	pLinkNode->pTreeNode = pTreeNode;
	if (pLinkNode == NULL)
		return ERROR;
	pTempLinkNode->nextLinkNode = pLinkNode;
	return OK;
}

LinkNode* pop(LinkQueue* pLinkQueue)
{
	LinkNode* pLinkNode = NULL;
	if (pLinkQueue->pHeadLinkNode == NULL)
		return ERROR;
	pLinkNode = pLinkQueue->pHeadLinkNode->nextLinkNode; // 取出当前头节点之后的一个pLinkNode结点
	pLinkQueue->pHeadLinkNode->nextLinkNode = pLinkQueue->pHeadLinkNode->nextLinkNode->nextLinkNode; // 将当前头结点指向下一个结点的下一个结点
	return pLinkNode;
}

Status checkQueueEmpty(LinkQueue* pLinkQueue)
{
	return pLinkQueue->pHeadLinkNode->nextLinkNode == NULL ? OK : ERROR;
}

// get tree's depth
ElemType getTreeDepth(TreeNode* pTreeNode)
{
	int iLeftDepth = 0;
	int iRightDepth = 0;
	if (pTreeNode != NULL)
	{
		iLeftDepth = getTreeDepth(pTreeNode->pLeftTree);
		iRightDepth = getTreeDepth(pTreeNode->pRightTree);
	}
	return iLeftDepth > iRightDepth ? (iLeftDepth + 1) : (iRightDepth + 1);
}

// init root tree node
Status initRootTreeNode(SqTree* pSqTree)
{
	if (pSqTree->pRootTreeNode != NULL)
		return ERROR;
	pSqTree->pRootTreeNode = malloc(sizeof(TreeNode));
	memset(pSqTree->pRootTreeNode, 0, sizeof(TreeNode));
	pSqTree->pRootTreeNode->nodeData = 1; //根节点的数据初始化为1
	if (pSqTree->pRootTreeNode != NULL)
		return OK;
	else
		return ERROR;
}

// insert a treeNode in tree
Status insertTreeNode(SqTree* pSqTree, ElemType elem)
{
	TreeNode* pRootTreeNode = pSqTree->pRootTreeNode;
	TreeNode* pTreeNode = pRootTreeNode->pLeftTree;
	TreeNode* pNewTreeNode = NULL;
	if (pTreeNode != NULL)
	{
		if (pTreeNode->pLeftTree != NULL)
		{
			pNewTreeNode = malloc(sizeof(TreeNode));
			if (pNewTreeNode == NULL)
				return ERROR;
			pNewTreeNode->nodeData = elem;
			pTreeNode->pLeftTree = pNewTreeNode;
		}
	}
	while (pTreeNode != NULL)
	{
		pTreeNode = pRootTreeNode->pLeftTree;
	}

	return OK;
}

// 删除指定的元素
Status deleteTreeNode(TreeNode* pTreeNode, ElemType elem)
{
	if (pTreeNode == NULL)
		return ERROR;

	// first travel left tree
	while (pTreeNode->pLeftTree != NULL)
	{
		if (pTreeNode->nodeData == elem)
		{
			// pTreeNode->nodeData == elem
			break;
		}
		pTreeNode = pTreeNode->pLeftTree;
	}

	while (pTreeNode->pRightTree != NULL)
	{

	}

	return OK;
}

// 层序插入结点的实现
Status insertTreeNodeViaLayerTravel(SqTree* pSqTree, ElemType elem)
{
	TreeNode* pInsertTreeNode = NULL;
	LinkQueue linkQueue;
	LinkNode* pLinkNode = NULL;
	int iRightFlag = 0;
	int iLeftFlag = 0;
	printf("test travel for layer...\n");
	memset(&linkQueue, 0, sizeof(LinkQueue));
	initLinkQueue(&linkQueue);
	// 压入当前的根结点作为起步操作
	push(&linkQueue, pSqTree->pRootTreeNode);
	// 层序遍历当前空结点的地方
	while (!checkQueueEmpty(&linkQueue))
	{
		// 第一次的话就是弹出一个存储根节点的pLinkNode
		pLinkNode = pop(&linkQueue);
		printf("current get a node -> %d\n", pLinkNode->pTreeNode->nodeData);
		// 如果当前的结点的左结点是为空的话,那么就直接break
		if (pLinkNode->pTreeNode->pLeftTree == NULL)
		{
			// 此时的话表示当前的结点的左结点是为空的,那么就要在当前的结点的左边插入一个结点
			pInsertTreeNode = malloc(sizeof(TreeNode));
			memset(pInsertTreeNode, 0, sizeof(TreeNode));
			pInsertTreeNode->nodeData = elem;
			pLinkNode->pTreeNode->pLeftTree = pInsertTreeNode;
			break;
		}
		else{
			push(&linkQueue, pLinkNode->pTreeNode->pLeftTree);
		}
		// 如果当前的结点的右结点是为空的话,同样也break
		if (pLinkNode->pTreeNode->pRightTree == NULL)
		{
			// 此时的话表示当前的结点的左结点是为空的,那么就要在当前的结点的右边插入一个结点
			pInsertTreeNode = malloc(sizeof(TreeNode));
			memset(pInsertTreeNode, 0, sizeof(TreeNode));
			pInsertTreeNode->nodeData = elem;
			pLinkNode->pTreeNode->pRightTree = pInsertTreeNode;
			break;
		}
		else{
			push(&linkQueue, pLinkNode->pTreeNode->pRightTree);
		}
	}
	// 上面出来了之后那么说明当前的pLinkNode指针的左子树的指针或者右子树的指针为空
	// 那么此时就可以进行插入操作了
	/*
	pInsertTreeNode = malloc(sizeof(TreeNode));
	memset(pInsertTreeNode, 0, sizeof(TreeNode));
	pInsertTreeNode->nodeData = elem;
	if (iLeftFlag == 1)
		pLinkNode->pTreeNode->pLeftTree = pInsertTreeNode;
	else if (iRightFlag == 1)
		pLinkNode->pTreeNode->pRightTree = pInsertTreeNode;*/
	return OK;
}

// 层序遍历/层次遍历
Status layerTravel(SqTree* pSqTree)
{
	LinkQueue linkQueue;
	LinkNode* pLinkNode = NULL;
	memset(&linkQueue, 0, sizeof(LinkQueue));
	initLinkQueue(&linkQueue);
	push(&linkQueue, pSqTree->pRootTreeNode);
	while (!checkQueueEmpty(&linkQueue))
	{
		pLinkNode = pop(&linkQueue);
		printf("current get a node -> %d\n", pLinkNode->pTreeNode->nodeData);
		if (pLinkNode->pTreeNode->pLeftTree != NULL)
			push(&linkQueue, pLinkNode->pTreeNode->pLeftTree);
		if (pLinkNode->pTreeNode->pRightTree != NULL)
			push(&linkQueue, pLinkNode->pTreeNode->pRightTree);
	}
	return OK;
}

// 搜索二叉树实现
Status searchTreeNode(TreeNode* pTreeNode)
{
	if (pTreeNode != NULL)
	{

	}
	return OK;
}

int main()
{
	SqTree sqTree;
	int iSize;
	printf("init tree node size -> ");
	scanf("%d", &iSize);
	// init treeRootNode
	memset(&sqTree, 0, sizeof(SqTree));
	initRootTreeNode(&sqTree);
	// test insert tree node via layer travel
	insertTreeNodeViaLayerTravel(&sqTree, 2);
	insertTreeNodeViaLayerTravel(&sqTree, 3);
	insertTreeNodeViaLayerTravel(&sqTree, 4);
	insertTreeNodeViaLayerTravel(&sqTree, 5);
	insertTreeNodeViaLayerTravel(&sqTree, 6);
	insertTreeNodeViaLayerTravel(&sqTree, 7);
	// use layer to travel the tree
	printf("use layer to travel the tree\n");
	printf("==============================\n");
	layerTravel(&sqTree);
	// base on pre and middle to create a tree;
	
	return 0;
}

测试用例

------1
----2---3
---4-5-6-7

运行结果如下

posted @ 2022-04-03 10:09  zpchcbd  阅读(100)  评论(0)    收藏  举报