【2月5日~2月6日PAT刷题笔记】——数据结构专题(2)树/二叉树的遍历,完全二叉树的判断,AVL树的插入旋转,二叉搜索树

1.树/二叉树的遍历

1020 Tree Traversals (25分)

1086 Tree Traversals Again (25分)

1102 Invert a Binary Tree (25分)

1079 Total Sales of Supply Chain (25分)

1090 Highest Price in Supply Chain (25分)

1094 The Largest Generation (25分)

1106 Lowest Price in Supply Chain (25分)

1138 Postorder Traversal (25分)

1151 LCA in a Binary Tree (30分)

1004 Counting Leaves (30分)

1053 Path of Equal Weight (30分)

1115 Counting Nodes in a BST (30分)

1127 ZigZagging on a Tree (30分)

大部分题目都采用二叉树的静态写法,但有部分采用静态写法会出现段错误的情况,可改为动态存储

以上题目都比较基础,考前条一两道热热手即可,在此就不单独一道道写题解,工程量也比较大

2.二叉查找树(BST)

1043 Is It a Binary Search Tree (25分)

1064 Complete Binary Search Tree (30分)

1099 Build A Binary Search Tree (30分)

总结:这类题目类型主要是:给你节点个数和值,还有他们之间的左右关系,只有一种方法填入这些节点值使之成为二叉查找树。主要就是考你如何建树。

解决此类问题的核心知识点:二叉查找树的中序遍历是有序的

以1099为例

                                     1099 Build A Binary Search Tree (30分)

把给的序列排序后,在中序遍历时赋值即可

#include<bits/stdc++.h>
using namespace std;
struct node{
	int data;
	int l,r;
}a[105];
int b[105],level[10005];
int pointers=0;int n;
void inorder(int root){
	if(root==-1) return;
	inorder(a[root].l);
	a[root].data=b[pointers++];
	inorder(a[root].r);
}
void bfs(int root){
	int num=0;
	queue<int>que;
	que.push(root);
	while(!que.empty()){
		int A=que.front();
		que.pop();
		printf("%d",a[A].data);
		num++;
		if(num!=n) printf(" ");
		else printf("\n");
		if(a[A].l!=-1) que.push(a[A].l);
		if(a[A].r!=-1) que.push(a[A].r);
	}
}
int main(){
	
	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i].l>>a[i].r;
	for(int i=0;i<n;i++) cin>>b[i];
	sort(b,b+n);
	inorder(0);
	bfs(0);
	return 0;
}

3.完全二叉树的判断

1110 Complete Binary Tree (25分)

知识点:给你一颗二叉树,判断是不是完全二叉树

思路:dfs遍历这颗二叉树,得到最大的节点编号,在与节点个数n比较,相等即为一颗完全二叉树

下面我来解释一下

很简单,根据完全二叉树的定义,他的节点都是靠左一个个排列的,最大节点编号一定和节点个数n是相等的,不相等说明出现了空位置

                                             1110 Complete Binary Tree (25分)

#include<bits/stdc++.h>
using namespace std;
int vis[10000];
vector<int>ve[10000];
int nums[10000],maxidx=-1,ans;
void dfs(int root,int idx) {
	if(root==-1) return;
	if(idx>maxidx){
		maxidx=idx;
		ans=root;
	}
	dfs(ve[root][0],idx*2);
	dfs(ve[root][1],idx*2+1);
}
int main() {
	bool flag=false;
	int n,numa,numb,root=0;
	cin>>n;
	string a,b;
	for(int i=0; i<n; i++) {
		cin>>a>>b;
		if(a[0]=='-') numa=-1;
		else numa=stoi(a);
		if(b[0]=='-') numb=-1;
		else numb=stoi(b);
		if(numa==-1&&numb!=-1) flag=true;
        if(numa!=-1)
		vis[numa]=1;
        if(numb!=-1)
		vis[numb]=1;
		ve[i].push_back(numa);
		ve[i].push_back(numb);
	}
	while(vis[root]) root++;
	dfs(root,1);
	if(maxidx==n){
		printf("YES %d\n",ans);
	} else printf("NO %d\n",root);
	return 0;
}

4.平衡二叉树(AVL树)

1066 Root of AVL Tree (25分)

1123 Is It a Complete AVL Tree (30分)

熟练掌握AVL树插入时四种旋转方法的思想和代码

node *rotateRight(node *root) {
	node *t=root->l;
	root->l=t->r;
	t->r=root;
	return t;
}
node *rotateLeft(node *root) {
	node *t=root->r;
	root->r=t->l;
	t->l=root;
	return t;
}
node *rotateRightLeft(node *root) {
	root->r=rotateRight(root->r);
	return rotateLeft(root);
}
node *rotateLeftRight(node *root) {
	root->l=rotateLeft(root->l);
	return rotateRight(root);
}
int getHeight(node *root) {
	if(root==NULL) return 0;
	else return max(getHeight(root->l),getHeight(root->r))+1;
}
node *insert(node *root,int val) {
	if(!root) {
		root=new node();
		root->val=val;
		root->l=root->r=NULL;
	} else if(val<root->val) {
		root->l=insert(root->l,val);
		if(getHeight(root->l)-getHeight(root->r)==2)
			root=val<root->l->val?rotateRight(root):rotateLeftRight(root);
	} else {
		root->r=insert(root->r,val);
		if(getHeight(root->l)-getHeight(root->r)==-2)
			root=val>root->r->val?rotateLeft(root):rotateRightLeft(root);
	}
	return root;
}

                                           1123 Is It a Complete AVL Tree (30分)

#include<bits/stdc++.h>
using namespace std;
int maxID=-1,level[100005];
struct node {
	struct node *l,*r;
	int val;
};
void dfs(node *root,int lev) {
	if(!root) return;
	maxID=max(maxID,lev);
	level[lev]=root->val;
	dfs(root->l,lev*2);
	dfs(root->r,lev*2+1);
}
node *rotateRight(node *root) {
	node *t=root->l;
	root->l=t->r;
	t->r=root;
	return t;
}
node *rotateLeft(node *root) {
	node *t=root->r;
	root->r=t->l;
	t->l=root;
	return t;
}
node *rotateRightLeft(node *root) {
	root->r=rotateRight(root->r);
	return rotateLeft(root);
}
node *rotateLeftRight(node *root) {
	root->l=rotateLeft(root->l);
	return rotateRight(root);
}
int getHeight(node *root) {
	if(root==NULL) return 0;
	else return max(getHeight(root->l),getHeight(root->r))+1;
}
node *insert(node *root,int val) {
	if(!root) {
		root=new node();
		root->val=val;
		root->l=root->r=NULL;
	} else if(val<root->val) {
		root->l=insert(root->l,val);
		if(getHeight(root->l)-getHeight(root->r)==2)
			root=val<root->l->val?rotateRight(root):rotateLeftRight(root);
	} else {
		root->r=insert(root->r,val);
		if(getHeight(root->l)-getHeight(root->r)==-2)
			root=val>root->r->val?rotateLeft(root):rotateRightLeft(root);
	}
	return root;
}
int main() {
	int n;
	node *root=NULL;
	cin>>n;
	for(int i=0; i<n; i++) {
		int num;
		cin>>num;
		root=insert(root,num);
	}
	dfs(root,1);
	int cnt=0;
	for(int i=1;; i++) {
		if(level[i]) {
			cnt++,printf("%d%c",level[i],cnt==n?'\n':' ');
			if(cnt==n) break;
		}
	}
	if(maxID==n) printf("YES\n");
	else printf("NO\n");

	return 0;
}
原创文章 70 获赞 25 访问量 7165

猜你喜欢

转载自blog.csdn.net/weixin_43727229/article/details/104197884