二叉树的静态实现

二叉树的静态实现可以满足完全不使用指针,而简单使用数组来完成二叉树的所有操作。

在定义二叉树时,采用的是二叉链表的结构,如下所示:

struct node{
	typename data;//数据域
	node *lchild;//指向左子树的根结点的指针
	node *rchild;//指向右子树的根结点的指针 
};

在这个定义中,为了能够实时控制新生成的结点的个数,结构体node中的左右指针域都采用了指针。静态的二叉链表不需要使用指针即可实现。

 

静态的二叉链表的定义:

 

结点的左右指针域均采用int型来代替,用来表示左右子树的根节点在数组中的下标。为此需要建立一个大小为结点上限个数的node型数组,所有动态生成的结点都直接使用数组中的结点,所有对指针的操作均改为对数组下标的访问。于是,结点node的定义更改如下:

struct node{
	typedefname data;//数据域
	int lchild;//指向左子树的指针域
	int rchild;//指向右子树的指针域 
}Node[maxn];//结点数组,maxn为结点上限个数 

在这样的定义下,结点的动态生成就可以转变为如下的静态的指定:

int newNode(int v){
	//分配一个Node型数组中的结点给新结点,index为其下标
	Node[index].data=v;
	Node[index].lchild=-1;//以-1或maxn表示空,因为数组范围是0-maxn-1 
	Node[index].rchild=-1;
	return index++; 
}

 下面给出二叉树的查找、插入、建立的代码,与使用指针的代码有所区别。

//查找,root为根节点在数组中的下标
void search(int root,int x,int newdata){
	if(root==-1){
		//用-1来代替null
		return;//递归的边界 
	}
	if(Node[root]==x){
		//找到数据域为x的结点,更改新的数据域
		Node[root]=newdata; 
	}
	search(Node[root].lchild,x,newdata);//在左子树中搜索x(递归式)
	search(Node[root].rchild,x,newdata);
} 
//插入,root为根节点在数组中的下标,记得加引用
void insert(int &root,int x){
	if(root==-1){
		//查找失败,边界
		root=newNode(x);//给root以新的结点
		return; 
	}
	if(由二叉树的性质x应该插入左子树){
		insert(Node[root].lchild,x);
	}else{
		insert(Node[root].rchild,x);
	}
} 

//二叉树的建立,函数返回根节点root的下标
int Create(int data[],int n){
	int root=-1;//建立根节点
	for(int i=0;i<n;i++){
		insert(root,data[i]);
	} 
	return root;//返回二叉树的根节点在数组中的下标 
} 

关于二叉树的先序遍历、中序遍历、后序遍历、层次遍历也应该做相应的转换。

//先序遍历
void preorder(int root){
	if(root==-1){
		return;//到达空树,递归边界 
	}
	//访问根节点root,例如将其数据输出
	printf("%d\n",Node[root].data);
	//访问左子树
	preorder(Node[root].lchild);
	//访问右子树
	preorder(Node[root].rchild); 
} 

//中序遍历
void inorder(int root){
	if(root==-1){
		return;//到达空树,递归边界 
	}
	//访问左子树
	preorder(Node[root].lchild);
	//访问根节点root,例如将其数据输出
	printf("%d\n",Node[root].data);
	//访问右子树
	preorder(Node[root].rchild); 
} 

//后序遍历
void postorder(int root){
	if(root==-1){
		return;//到达空树,递归边界 
	}
	//访问左子树
	preorder(Node[root].lchild);
	//访问右子树
	preorder(Node[root].rchild); 
	//访问根节点root,例如将其数据输出
	printf("%d\n",Node[root].data);
} 

//层序遍历
void LayerOrder(int root){
	queue<int>q;//此处队列里存放结点的下标
	q.push(root);//将根节点地址入队
	while(!q.empty()){
		int now=q.front();//取出队首元素
		q.pop();
		printf("%d",Node[now].data);
		if(Node[now].lchild!=-1) q.push(Node[now].lchild);
		if(Node[now].rchild!=-1) q.push(Node[now].rchild);//右子树非空 
		
	} 
} 


 二叉树实现了完全的静态转换

 

 

 

上一篇:Python算法——二叉树镜像反转


下一篇:【数据结构】(二叉树)求二叉树带权路径长度(WPL)递归&&非递归