看数据结构写代码(23) 二叉链表的实现

本文探讨了二叉链表的实现,介绍大部分操作基于递归算法,并提及非递归算法利用链栈和链队列。同时指出,对于求解树的宽度的代码存在错误,已在后续文章《看数据结构(25)》中修正。
摘要由CSDN通过智能技术生成

二叉链表的实现 大部分操作 都在 递归算法的基础上 进行的。部分非递归算法,借用了 链栈 和 链队列。可以从以前的文章中 摘取。

树的大部分操作 都可以在下面 找到

下面 上代码:

注意:由于 对树的宽度的理解不够,下面 求 树的宽度代码有错误,正确的代码,在 《看数据结构(25)》中 重新书写。

// binaryTree.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <cstdlib>
#include "stack.h"
#include "queue.h"

typedef int ElementType;

typedef  struct TreeNode
{
	ElementType data;
	TreeNode * leftChild;
	TreeNode * rightChild;
} * Tree;

void treeInit(Tree * tree){
	*tree = NULL;
}
//其实 自己 不懂 这个 函数 初始化...
E_State treeCreate(Tree *tree){
	ElementType data;
	scanf("%d",&data);
	if (data == 0)
	{
		*tree = NULL;
	}else
	{
		*tree = (Tree)malloc(sizeof(TreeNode));
		(*tree)->data = data;
		treeCreate(&(*tree)->leftChild);
		treeCreate(&(*tree)->rightChild);
	}
	return E_State_Ok;
}

E_State treeCopy(Tree * to,Tree from){
	if(from != NULL){
		*to = (Tree) malloc(sizeof(TreeNode));
		(*to)->data = from->data;
		treeCopy(&(*to)->leftChild,from->leftChild);
		treeCopy(&(*to)->rightChild,from->rightChild);
	}
	else
	{
		*to = NULL;
	}
	return E_State_Error;
}

//后序遍历
void treeClear(Tree * tree){
	if (tree != NULL)
	{
		if ((*tree)->leftChild != NULL)
		{
			treeClear(&(*tree)->leftChild);
		}
		else if((*tree)->rightChild != NULL)
		{
			treeClear(&(*tree)->rightChild);
		}
		free(*tree);
		*tree = NULL;
	}
}

void treeDestory(Tree * tree){
	treeClear(tree);
}

bool treeEmpty(Tree tree){
	//if (tree->leftChild == NULL && tree->rightChild == NULL) 错误
	//空表 的概念,你懂吗?
	if(tree == NULL)
	{
		return true;
	}
	return false;
}

int treeLen(Tree tree){
	if (tree != NULL)
	{
		return treeLen(tree->leftChild) + treeLen(tree->rightChild) + 1;
	}
	else
	{
		return 0;
	}
}



int treeDepth(Tree tree){
	if (tree != NULL)
	{
		int leftDepth = treeDepth(tree->leftChild);
		int rightDepth = treeDepth(tree->rightChild);
		return (leftDepth > rightDepth ? leftDepth : rightDepth) + 1;
	}
	else
	{
		return 0;
	}
}

//统计叶子节点的个数
int treeLeafCount(Tree tree){
	if (tree != NULL)
	{
		if (tree->leftChild == NULL && tree->rightChild == NULL)
		{
			return 1;
		}
		return treeLeafCount(tree->leftChild) + treeLeafCount(tree->rightChild);
	}
	return 0;
}
//判断节点的层数,先序法
int treeLevel(Tree tree,Tree child){
	if (tree != NULL)
	{
		if (tree == child)
		{
			return 1;
		}
		int left = treeLevel(tree->leftChild,child);
		if (left > 0)
		{
			return left +1;
		}
		int right = treeLevel(tree->rightChild,child);
		if (right > 0)
		{
			return right +1;
		}
	}
	return 0;
}

//求二叉树的宽度

int treeWidth(Tree tree){
	if (tree != NULL)
	{
		if (tree->leftChild == NULL && tree->rightChild == NULL)
		{
			return 1;
		}
		return treeWidth(tree->leftChild) + treeWidth(tree->rightChild);
	}
	return 0;
}

//中序非递归
//利用栈 
Tree treeParent(Tree tree,Tree child){
	if (tree != NULL)
	{
		linkStack stack;
		stackInit(&stack);
		stackPush(&stack,tree);
		while (!stackEmpty(stack))
		{
			Tree t;
			while (stackGetTop(stack,&t) && t) stackPush(&stack,t->leftChild);
			stackPop(&stack,&t);//将空 出栈
			if (! stackEmpty(stack) )
			{
				stackPop(&stack,&t);
				if (t ->leftChild == child || t->rightChild == child)
				{
					return t;
				}
				stackPush(&stack,t->rightChild);
			}

		}
		stackDestory(&stack);
	}
	return NULL;
}

Tree treeLeftChildren(Tree parent){
	if (parent != NULL)
	{
		return parent->leftChild;
	}
	return NULL;
}

Tree treeRightChildren(Tree parent){
	if (parent != NULL)
	{
		return parent->rightChild;
	}
	return NULL;
}

Tree treeLeftSibling(Tree tree,Tree brother){
	TreeNode * parent = treeParent(tree,brother);
	if (parent != NULL)
	{
		if (tree->leftChild != brother)
		{
			return tree->leftChild;
		}
	}
	return NULL;
}

Tree treeRightSibling(Tree tree,Tree brother){
	TreeNode * parent = treeParent(tree,brother);
	if (parent != NULL)
	{
		if (tree->rightChild != brother)
		{
			return tree->rightChild;
		}
	}
	return NULL;
}

E_State treeInsert(Tree * tree,bool isLeft,Tree childNode){
	if (tree!= NULL)
	{
		if (isLeft && (*tree)->leftChild == NULL)
		{
			(*tree)->leftChild = childNode;
			return E_State_Ok;
		}
		else if(!isLeft && (*tree)->rightChild == NULL)
		{
			(*tree)->rightChild = childNode;
			return E_State_Ok;
		}
	}
	return E_State_Error;
}

void treeDelete(Tree * tree,bool isLeft){
	if (tree != NULL)
	{
		isLeft ? treeClear(&(*tree)->leftChild) : treeClear(&(*tree)->rightChild);;
	}
}

void preOrderTraverse(Tree tree){
	if (tree != NULL)
	{
		printf("%d\t",tree->data);
		preOrderTraverse(tree->leftChild);
		preOrderTraverse(tree->rightChild);
	}
}

void inOrderTraverse(Tree tree){
	if (tree != NULL)
	{
		inOrderTraverse(tree->leftChild);
		printf("%d\t",tree->data);
		inOrderTraverse(tree->rightChild);
	}
}

void postOrderTraverse(Tree tree){
	if (tree != NULL)
	{
		postOrderTraverse(tree->leftChild);
		postOrderTraverse(tree->rightChild);
		printf("%d\t",tree->data);
	}
}

//层序
//利用队列
void levelOrderTraverse(Tree tree){
	if (tree != NULL)
	{
		LinkQueue queue;
		queueInit(&queue);
		enqueue(&queue,tree);
		while (dequeue(&queue,&tree) && tree)
		{
			printf("%d\t",tree->data);
			if (tree->leftChild != NULL)
			{
				enqueue(&queue,tree->leftChild);
			}
			if (tree->rightChild != NULL)
			{
				enqueue(&queue,tree->rightChild);
			}
		}
		queueDestory(&queue);
	}
}


int _tmain(int argc, _TCHAR* argv[])
{
	Tree tree;
	printf("---------------创建树-----------------\n");
	treeCreate(&tree);
	printf("---------------创建子树-----------------\n");
	Tree childTree;
	treeCreate(&childTree);
	treeInsert(&tree,false,childTree);
	treeDelete(&(tree->rightChild),true);
	printf("------------先序遍历----------------\n");
	preOrderTraverse(tree);
	printf("\n------------中序遍历----------------\n");
	inOrderTraverse(tree);
	printf("\n------------后序遍历----------------\n");
	postOrderTraverse(tree);
	printf("\n------------层序遍历----------------\n");
	levelOrderTraverse(tree);
	char * isEmpty = treeEmpty(tree) ? "是" : "不是";
	int len = treeLen(tree);
	int depth = treeDepth(tree);
	int leafCount = treeLeafCount(tree);
	int width = treeWidth(tree);
	printf("树 是否为空:%s\n树长:%d\n树深:%d,树的叶子树:%d,树的宽度是:%d\n",isEmpty,len,depth,leafCount,width);
	Tree  child = treeLeftChildren(tree);
	child = treeLeftChildren(child);
	Tree parent = treeParent(tree,child);
	Tree leftChild = treeLeftChildren(child);
	Tree rightChild = treeRightChildren(child);
	Tree leftSibling = treeLeftSibling(tree,child);
	Tree rightSibling = treeRightSibling(tree,child);
	int level = treeLevel(tree,child);
	printf("%d 的节点层数是:%d, 父亲是 %d, 左孩子是 :%d,右孩子是 %d,左兄弟是:%d,右兄弟是:%d",level,child->data,parent->data,leftChild->data,rightChild->data,leftSibling->data,rightSibling->data);
	printf("\n------------二叉树的拷贝----------------\n");
	Tree copy;
	treeCopy(&copy,tree);
	preOrderTraverse(copy);
	treeDestory(&tree);
	treeDestory(&childTree);
	treeDestory(&copy);
	return 0;
}

运行截图:


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值