【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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章