在定义二叉树时,采用的是二叉链表的结构,如下所示:
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);
}
}
}