树和二叉树

树的定义

树是一种重要的数据结构,它是由n个结点的有限集,对于非空的树

(1)有且仅有一个称之为根的结点

(2)任意一个结点下面可以接m个互不相交的有限集,称这为这棵树的子树。

对于树中的每个结点,它的子结点有且仅有两个或不存在子结点,这棵树就可以被称为二叉树

而二叉树又被分为满二叉树,完全二叉树,非完全二叉树

1.满二叉树

每一层上的结点数都是最大结点数。

2.完全二叉树

若一个二叉树深度为k,结点数为n,且从1到n的每个结点都与深度为k的完全二叉树一一对应,就可以称这棵树为完全二叉树。

上图中的二叉树既是完全二叉树,又是满二叉树。

二叉树的存储结构

1.顺序存储结构

顺序存储结构使用一组地址连续的单元来存放数据元素(数组),仅适用于完全二叉树,若存放单结点的树会造成严重的空间浪费。以下为借助顺序存储结构实现的二叉树及其遍历。

#include<iostream>
using namespace std;
struct node
{        
    char lc,rc,fa;
};
node tree[1000];
void find(char root)
{
	cout<<root;
	if(tree[root].lc!='*')
	find(tree[root].lc);
	if(tree[root].rc!='*')
	find(tree[root].rc);
}
int main()
{
    int n;
    cin>>n;
    char a,b,c,root;
    for(int i=0;i<n;i++)
    {
    	cin>>a>>b>>c;
    	if(i==0)
    	{
    		root=a;
    		tree[a].lc=b;
    		tree[a].rc=c;
		}
		else
		{
    		tree[a].lc=b;
    		tree[a].rc=c;
		}
	}
	find(root);
    return 0;
}

2.链式存储结构

对于一般的二叉树,都是用的是链式存储结构。二叉树的结点至少包含三个域,即数据域和左右指针域(二叉链表)。为了便于找到某个结点的双亲,还可以在结点结构中加入一个指向双亲结点的指针域(三叉链表)。

typedef struct node
{
  TElemType data;//数据域
  struct node *leftchild *rightchild;//结点中的左右孩子指针
}node,*tree;

遍历二叉树

遍历二叉树的方式:

1.先根遍历

2.中根遍历

3.后根遍历

区别只在访问根节点在遍历左子树和右子树的之前之后还是中间。

此处以中序遍历为例

if(T)
{
  travel(T->leftchild);
  cout<<T->data;
  travel(T->rightchild);
}

先根和后根改变语句顺序即可。

若不借助递归来遍历二叉树,也可以选择借助栈来进行遍历,若根指针非空则将根指针压入栈中,遍历左子树。若根指针为空,则弹出栈顶元素,遍历右子树。

这两种遍历方式的时间复杂度均为O(n),因此可以按照情况任意选择。

借助二叉树的遍历算法,可以建立二叉树。

void createtree(bitree &T)
{
  cin>>p;
  if(停止条件)
  T=NULL;
  else
  {
     T=new node;
     T->data=ch;
     createtree(T->leftchild);
     createtree(T->rightchild);
  }
}

线索二叉树

将二叉树的域进一步扩大,增加Ltag和Rtag两个值

typedef struct node
{
  TElemType data;//数据域
  struct node *leftchild *rightchild;//结点中的左右孩子指针
  int Ltag,Rtag;//增加两个线索变量
}node,*tree;

若线索变量值为0,child域指示结点的孩子;反之指示结点的父亲,即相当于为二叉树增加了一个方向,可以从第一个或最后一个结点开始遍历。

树的存储结构

1.双亲表示法

结点中只有双亲,不包括孩子。

2。孩子表示法

结点中只有孩子,不包括双亲。

3.孩子兄弟法

typedef struct node
{
  TElemType data;//数据域
  struct node *firstchild *nextsibling;//结点中的左右孩子指针
  int Ltag,Rtag;//增加两个线索变量
}node,*tree;

查找结点时只需要从第一个孩子开始找需要的兄弟即可。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值