1. 找最大值与最小值
void countMaxAndMin(Bitree T) {
Queue Q;
initQueue(Q);
Bitree p = NULL;
EnQueue(Q, T);
int max = T->data, min = T->data;
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p->data > max) {
max = p->data;
}if (p->data < min) {
min = p->data;
}
if (p->lchild) {
EnQueue(Q, p->lchild);
}
if (p->rchild) {
EnQueue(Q, p->rchild);
}
}
printf("最大值是:%d\n,最小值是:%d", max, min);
}
2. 求二叉树的深度
在非递归算法中,需要注意的是工作变量r始终指向当前层的最后一个节点,要判断当前层的节点是否全部入队,关键在于front指针,如果front指针走到了下一层节点入队前rear的前一个位置(即r的位置),那么说明此时,第i层入队的节点已经全部出队,第i层的所有孩子,即第i+1层的节点全部入队,此时,层数就要加1
void countdepth(Bitree T) {
Queue Q;
initQueue(Q);
Bitree p = NULL;
int r = 0; //r始终指向当前层的最后一个节点的标号,初始化指向根节点
int level = 0;
EnQueue(Q, T);
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p->lchild) {
EnQueue(Q, p->lchild);
}if (p->rchild) {
EnQueue(Q, p->rchild);
}
if (r == Q.front - 1){
level++;
r = Q.rear - 1;
}
}
printf("总层数:%d\n", level);
}
3. 求二叉树的宽度
同样是利用了rear和front指针,当某一层节点全部入队后,此时rear和front指针的差距就是当前层节点的个数,若要统计最大宽度,那么只需要不断迭代更新,如果当前层节点个数大于上一次记录的该层最大节点个数,就更新
void countwidth(Bitree T) {
Queue Q;
initQueue(Q); //Q.front = Q.rear = 0
Bitree p = NULL;
int r = 0; //r始终指向当前层最后一个节点
int width = 1; //width初始化设为第一次节点的个数
EnQueue(Q, T);
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p->lchild) {
EnQueue(Q, p->lchild);
}
if (p->rchild) {
EnQueue(Q, p->rchild);
}
if (r == Q.front - 1) {
if (width < Q.rear - Q.front) { //Q.rear-Q.front表示当前层节点的个数
width = Q.rear - Q.front;
}
r = Q.rear - 1;
}
}
printf("树的宽度是:%d\n", width);
}
4.求二叉树中第k层中的节点数量
int GetCountK(Bitree T,ElemType k) {
if (k == 0) { return 0; }
if (k == 1) { return 1; }
Queue Q;
initQueue(Q);
BitNode* p = T;
int r = 0, level = 0;
int count = 0;//count代表对应层数的节点数量
EnQueue(Q, p);
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p->lchild) {
EnQueue(Q, p->lchild);
}if (p->rchild) {
EnQueue(Q, p->rchild);
}
if (Q.front - 1 == r) {
level++;
r = Q.rear - 1;
if (level+1 == k) {
count = Q.rear - Q.front;
}
}
}
printf("\n");
return count;
}
5. 求值为x的节点所在层次
Bitree Level_ofX(Bitree T, ElemType x) {
Queue Q;
initQueue(Q);
Bitree p = NULL;
int levelX = 1, r = 1;//表示节点值为x的节点所在层次
EnQueue(Q, T);
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p->data == x) {
printf("值为%c的节点所在层次为:%d", x, levelX);
return T;
}
if (p->lchild) { EnQueue(Q, p->lchild); }
if (p->rchild) { EnQueue(Q, p->rchild); }
if (r = Q.front) {
levelX++;
r = Q.rear;
}
}
}
6. 交换二叉树的左右子树
如果当前访问节点不为空,且左右子树存在其一,那么就进行交换(这里很好理解,首先如果是空节点,肯定不用交换,其次,如果该节点没有子树,那么也肯定不用交换)
BitNode* swap(Bitree T) {
Queue Q;
initQueue(Q);
Bitree p = T;
EnQueue(Q, T);
while (!isEmptyQueue(Q)) {
p = DeQueue(Q, p);
if (p != NULL && (p->lchild || p->rchild)) {//如果当前访问节点不为空,且左右子树存在其一,那么就进行交换(这里很好理解,首先如果是空节点,肯定不用交换,其次,如果该节点没有子树,那么也肯定不用交换)
BitNode* temp;
temp = p->lchild;
p->lchild = p->rchild;
p->rchild = temp;
if (p->lchild) {
EnQueue(Q, p->lchild);
}if (p->rchild) {
EnQueue(Q, p->rchild);
}
}
}
printf("交换后的次序如下:");
LevelTraversal(T);
return T;
}
测试:
int main() {
char A[] = { 'A','B','C','D','E','F'};
char B[] = { 'C','B','A','E','D','F'};
char C[] = { 'C','B','E','F','D','A'};
//InvertLevel(buildFromPreIn(A, B, 0, 5, 0, 5));
//InvertLevel(buildFromPostIn(B, C, 0, 5, 0, 5));
//countLeaf(buildFromPreIn(A, B, 0, 5, 0, 5));
//countMaxAndMin(buildFromPreIn(A, B, 0, 5, 0, 5));
//countdepth(buildFromPreIn(A, B, 0, 5, 0, 5));
countwidth(buildFromPreIn(A, B, 0, 5, 0, 5));
}