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