7-2 是否完全二叉搜索树 (树 层序遍历 队列)

如果遇到了一个不为二度的结点,那么如果这棵树时完全树则这个结点后面必须全部是叶子。

有特别的情况,当这棵树只有两个结点时,根必然度数小于2,另一个结点必然是叶子,但这棵树也不是完全树。

所以当结点数大于2时可以用通用的方法处理,而结点只有两个时最好作为特殊情况直接输出。

至于层序遍历,可以使用队列。访问一个结点时,把它的左子放入队尾,再将右子放入队尾。上面一层的结点在队列中一定在下面一层的前面,并且从左向右排。

代码包括了树的建立,队列的使用,层序输出。在层序输出的函数里,顺便用两个bool变量进行了完全性的判断。

//输入大小
//输入数字
//	生成树
//	进行层序遍历
//	如果某一个结点的没有两个子树
		//那么接下去的结点都不能有两个子树

#define _CRT_SECURE_NO_WARNINGS
#include<stdlib.h>
#include<stdio.h>
#include<stdbool.h>

static int n;
//标记树的完全性
static bool sign1 = false;
static bool sign2 = false;



struct TNode{
    
    
	int  value;
	struct TNode* Left;
	struct TNode* Right;
};


struct TNode* insert(struct TNode* root, int data) {
    
    
	//新建叶子
	if (root == NULL) {
    
    
		root = (malloc)(sizeof(struct  TNode));
		root->value = data;
		root->Left = NULL;
		root->Right = NULL;
		return root;
	}
	else {
    
    
		if (data > root->value) {
    
    
			root->Left = insert(root->Left, data);
		}
		else {
    
    
			root->Right = insert(root->Right, data);
		}
	}
	return root;
}


//队列及操作
struct Queue {
    
    
	struct TNode* array[30];
	int front;
	int top;
	int count;
}q;

void initialQueue() {
    
    
	q.front = q.top = 0;
	q.count = 0;
}

void push(struct TNode* data) {
    
    
	q.array[q.top] = data;
	q.top++;
	q.count++;
}

struct TNode* pop() {
    
    
	struct TNode* data = q.array[q.front];
	q.front++;
	q.count--;
	return data;
}

struct TNode* front() {
    
    
	return q.array[q.front];
}

bool isEmpty() {
    
    
	return q.count == 0;
}



//队列方式实现层序输出
void levelOut(struct TNode* root) {
    
    
	//加入根结点
	push(root);
	while (!isEmpty()) {
    
    
		struct TNode* tempFront = pop();



		if (tempFront->Left != NULL) {
    
    
			push(tempFront->Left);
		}
		if (tempFront->Right != NULL) {
    
    
			push(tempFront->Right);
		}

		//输出控制.........
		if (!isEmpty())
			printf("%d ", tempFront->value);
		else
			printf("%d", tempFront->value);
		//... ......

		//判断完全性
		//有一个不为二度的结点 则后面的都要是叶子
		if (sign1== false&&(!(tempFront->Left != NULL && tempFront->Right != NULL))) {
    
    
			sign1 = true;
			continue;
		}
		if (sign1 == true) {
    
    
			if (!(tempFront->Left == NULL && tempFront->Right == NULL)) {
    
    
				sign2 = true;
			}
		}
		//特别讨论只有两个结点的情况
		if (n == 2) {
    
    
			sign2 = true;
		}
	
	}
		

	printf("\n");
	}




//在层序输出时做好标记
int main() {
    
    
	struct TNode* treeRoot = NULL;
	scanf("%d", &n);
	//导入结点
	for (int i = 0; i < n; i++) {
    
    
		int toInsert;
		scanf("%d", &toInsert);
		treeRoot= insert(treeRoot, toInsert);
	}
	levelOut(treeRoot);

	if (!sign2) {
    
    
		printf("YES");
	}
	else {
    
    
		printf("NO");
	}

	return 0;
}

猜你喜欢

转载自blog.csdn.net/roswellnotfound/article/details/108995500
今日推荐