【深入理解数据结构】二叉树实践

数据结构的本质:

数据结构就是研究数据的逻辑结构物理结构以及它们之间相互关系,并对这种结构定义相应的运算

什么是逻辑结构?

数据之间的逻辑关系,我们通常分成四种:

1)集合 , 结构中的数据元素除了同属于一种类型外,别无其它关系。

2)线性结构 , 结构中的数据元素之间存在一对一的关系。

3)树型结构 ,  结构中的数据元素之间存在一对多的关系。

4)图状结构或网状结构 , 结构中的数据元素之间存在多对多的关系。

什么是物理结构?

数据在内存中的存储形式,我们通常分成两种:

1)顺序存储,在内存中严格连续存放,可以通过数组来实现;

2)链式存储,在内存中不连续存放,可以通过指针来实现。

逻辑结构和物理结构的相互关系有什么意义?

逻辑结构越复杂,顺序存储缺点越明显,链式存储优点越突出。

注:以下均以链式存储来分析。

 

单向链表

typedef struct node
{
     datetype val;      //结点的内容
     struct node *next; //指向下一个结点
}

双向链表

typedef struct node
{
     datetype val;      //结点的内容
     struct node *head; //指向前一个结点
     struct node *rear; //指向后一个结点
}

二叉树

由一个根结点及两棵互不相交的左右子树组成,并且左右子树都是二叉树。

typedef struct btree
{
     datetype val; //结点内容
     btree *left;  //指向左子树
     btree *right; //指向右子树
}B;

 

/*
文件名:Btree.c
摘要:
1)利用递归的思想创建二叉树,先访问根节点,再访问左结点,最后访问右结点(先序遍历的思想——DLR)。
2)利用堆栈输出二叉树,遍历左树——入栈——出栈——遍历右树。

完成日期:2012-7-3 15:23
作者:黄路
*/
#include<stdio.h>
#include<stdlib.h>

typedef struct Bitree
{
	int data;
	struct Bitree *Lchild;   //左子树
	struct Bitree *Rchild;   //右子树
}BitreeNode;

typedef BitreeNode *LinkBitree;

typedef struct Stack
{
	LinkBitree data[20];
	int top,bottom;
}Stack;

typedef Stack *StackList;
//建树
LinkBitree CreatBitree();
//初始化栈
StackList InitStack();
//先序输出
void InorderTraverse(LinkBitree Head, StackList Stack);


int main()
{
	LinkBitree BitreeHead;
	StackList Stack;

	printf("请输入根结点的值:e = ");
	BitreeHead = CreatBitree();

	Stack = InitStack();

	InorderTraverse(BitreeHead, Stack);

	return 0;
}

/*
功能:利用‘递归的思想’创建 树
输入:键盘输入根节点
输出:树
*/
LinkBitree CreatBitree()
{
	int edata;//根结点
	LinkBitree Head;

	scanf("%d", &edata);
     //如果根节点为0,则停止在此根结点上建子树
	if(edata==0)
	{
		Head = NULL;
	}
	else
	{
          Head = (LinkBitree)malloc(sizeof(BitreeNode));
          //memory check
	     if(Head == NULL)
		{
			printf("内存分配失败!!");
		     exit(0);
		}
		else
		{
			Head->data = edata;
			printf("请输入结点%d的左孩子的值:e= ", Head->data);
			Head->Lchild = CreatBitree();
			printf("请输入结点%d的右孩子的值:e= ", Head->data);
			Head->Rchild = CreatBitree();
		}
	}
	return Head;
}

/*
功能:初始化栈
栈空间是用来存放 子树的。
*/
StackList InitStack()
{
	StackList Stack;
	Stack = (StackList)malloc(sizeof(Stack));
	if(Stack == NULL)
	{
		printf("内存分配失败!!");
		exit(0);
	}
	else
	{
		Stack->top = 0;
		Stack->bottom = 0;
	}
	return Stack;
}

//先访问根结点,再访问左树,再访问右树
void InorderTraverse(LinkBitree Head, StackList Stack)
{
	do
	{
		while (Head != NULL) //穷尽所有的左子树为止
		{
			printf("%d ", Head->data);     //打印左树的根结点
			Stack->data[Stack->top] = Head;//将访问过的子树入栈
			Stack->top++;                  //栈头
			Head = Head->Lchild;           //访问下一个左子树
		}
		if (Stack->top != 0)//穷尽栈为止
		{
			Stack->top--;
			Head = Stack->data[Stack->top]; //出栈
			Head = Head->Rchild;            //访问下一个右子树
		}
	}
	while(Stack->top != 0 || Head != NULL);
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值