二叉树的静态实现

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

struct node{
	typename data;
	node* lchild;
	node* rchild;
}; 
在这个定义中,为了能够实时控制新生成结点的个数,结构体node中的左右指针域都使用了指针,但如果要避免使用指针的话,就要采用静态二叉链表的方法。

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

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

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

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

二叉树的查找:

/*****查找,root为根结点在数组中的下标*****/
void search(int root, int x, int newdata){
	if(root == -1){
		return;
	}
	if(Node[root].data == x){
		Node[root].data = newdata;
	}
	search(Node[root].lchild, x, newdata);
	search(Node[root].rchild, x, newdata);
} 

二叉树的插入:

/*****插入,root为根结点在数组中的下标*****/
void insert(int &root, int x){
	if(root == -1){
		root = newNode(x);
		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;
	}
	printf("%d\n", Node[root].data);    //访问根结点,例如将其数据域输出 
	preOrder(Node[root].lchild);		//访问左子树 
	preOrder(Node[root].rchild);		//访问右子树 
}

二叉树的中序遍历:

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

二叉树的后序遍历:

void postOrder(int root){
	if(root == -1){		//递归边界 
		return;
	}
	postOrder(Node[root].lchild);		//访问左子树 
	postOrder(Node[root].rchild);		//访问右子树 
	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);
		}
	}
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值