(有任何问题欢迎留言或私聊 本文目的旨在给初学二叉树的朋友提供一个借鉴的模板:一个是指针版本,一个非指针版本。 在文末推荐几道经典例题、我的题解和经典博客,供大家学习。 已经了解二叉树的同学可以直接去看最下面的一些经典题目。点击左侧目录即可。 二叉树的很多相关定义在百度百科或者他人博客上都有,建议先看一下。
引入:
一个二叉树如下: 前序遍历: ABDHIEJCFG 中序遍历: HDIBJEAFCG 后序遍历: HIDJEBFGCA 层序遍历: ABCDEFGHIJ 特点: 1. 前序遍历中,根节点在第一位;后序遍历中,根节点在最后一位; 2. 中序遍历中,根节点的左右子树分别在根节点位置两边;
非指针版本:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N =
1005;
const int INF =
0x3f3f3f3f;
const LL mod =
1000000007;
const double eps =
1e-8;
struct BinaryTree{
int val;
int l;
int r;
BinaryTree(){val=
0;l=r=-
1;}
}tree[N];
int ar[N],ans[N],n,tot,t;
int pre[N],jing[N];
void build(
int k){
if(k>n)
return;
tree[++tot].val=ar[k];
tree[tot].l=tree[tot].r=-
1;
int i=
1;
while(
1){
if(ar[k]<tree[i].val){
if(tree[i].l!=-
1){
i=tree[i].l;
}
else{
tree[i].l=tot;
break;
}
}
else {
if(tree[i].r!=-
1){
i=tree[i].r;
}
else{
tree[i].r=tot;
break;
}
}
}
build(k+
1);
return;
}
void get_pre(
int k){
pre[++t]=tree[k].val;
if(tree[k].l!=-
1)get_pre(tree[k].l);
if(tree[k].r!=-
1)get_pre(tree[k].r);
return;
}
void get_jing(
int k){
jing[++t]=tree[k].val;
if(tree[k].r!=-
1)get_jing(tree[k].r);
if(tree[k].l!=-
1)get_jing(tree[k].l);
return;
}
void get_mid(
int k){
if(tree[k].l!=-
1)get_mid(tree[k].l);
ans[++t]=tree[k].val;
if(tree[k].r!=-
1)get_mid(tree[k].r);
}
void get_mid2(
int k){
if(tree[k].r!=-
1)get_mid2(tree[k].r);
ans[++t]=tree[k].val;
if(tree[k].l!=-
1)get_mid2(tree[k].l);
}
void get_la(
int k){
if(tree[k].l!=-
1)get_la(tree[k].l);
if(tree[k].r!=-
1)get_la(tree[k].r);
ans[++t]=tree[k].val;
}
void get_la2(
int k){
if(tree[k].r!=-
1)get_la2(tree[k].r);
if(tree[k].l!=-
1)get_la2(tree[k].l);
ans[++t]=tree[k].val;
}
void output(){
for(
int i=
1;i<=n;++i){
if(i==n)
printf(
"%d\n",ans[i]);
else printf(
"%d ",ans[i]);
}
}
int main(){
scanf(
"%d",&n);
for(
int i=
1;i<=n;++i){
scanf(
"%d",&ar[i]);
}
tot=
1;
tree[
1].val=ar[
1];
tree[
1].l=tree[
1].r=-
1;
build(
2);
t=
0;
get_pre(
1);
t=
0;
get_jing(
1);
return 0;
}
指针版本:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N =
1005;
const int INF =
0x3f3f3f3f;
const LL mod =
1000000007;
const double eps =
1e-8;
typedef struct BinaryTree {
int val;
BinaryTree* left;
BinaryTree* right;
BinaryTree(){}
BinaryTree(
int data)
: val(data), left(
nullptr), right(
nullptr) {}
}*tree;
int n;
int post[N],mid[N],pre[N];
tree build(
int k,
int *mid,
int *post,
int inl,
int inr){
int i,j;
if(k<=
0)
return nullptr;
if(inl>inr)
return nullptr;
tree p;
p=
new BinaryTree;
p->left=p->right=
nullptr;
p->val=post[k-
1];
for(i=
0;i<n;++i){
if(mid[i]==post[k-
1])
break;
}
for(j=
0;j<n;++j){
if(*mid==mid[j])
break;
}
int l=i-j;
p->left=build(l,mid,post,inl,inl+l-
1);
p->right=build(k-l-
1,mid+l+
1,post+l,inl+l+
1,inr);
return p;
}
void bfs(tree head){
queue<tree>Q;
while(!Q.empty())Q.pop();
Q.push(head);
int s=
0;
while(!Q.empty()){
tree u=Q.front();Q.pop();
pre[s++]=u->val;
if(u->left!=
nullptr)Q.push(u->left);
if(u->right!=
nullptr)Q.push(u->right);
}
for(
int i=
0;i<s;++i){
if(i==s-
1)
printf(
"%d\n",pre[i]);
else printf(
"%d ",pre[i]);
}
}
int main(){
scanf(
"%d",&n);
for(
int i=
0;i<n;++i){
scanf(
"%d",&post[i]);
}
for(
int i=
0;i<n;++i){
scanf(
"%d",&mid[i]);
}
tree root=
new BinaryTree;
root->left=root->right=
nullptr;
root=build(n,mid,post,
0,n-
1);
bfs(root);
return 0;
}
例题:
二叉树:PATL2-004. 这是二叉搜索树吗? 树的遍历:PATL2-006. 树的遍历 二叉树:PATL2-011. 玩转二叉树 完全二叉树:PATL3-010. 是否完全二叉搜索树 层序遍历例题:数据结构实验之二叉树五:层序遍历
我的题解
推荐博客:
二叉树前中后序遍历,DFS与BFS遍历二叉树 层序遍历讲解
二叉搜索树变双向链表:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N =
1005;
const int INF =
0x3f3f3f3f;
const LL mod =
1000000007;
const double eps =
1e-8;
struct binaryTree{
int val;
binaryTree* l;
binaryTree* r;
}cw[N];
typedef binaryTree* bsTree;
int ar[N],n;
bsTree last,fi;
bsTree insert(bsTree cur,
int x){
if(cur==
nullptr){
cur =
new binaryTree;
cur->val=x;
cur->l=
nullptr;
cur->r=
nullptr;
return cur;
}
if(cur->val>x){
cur->l=insert(cur->l,x);
}
else if(cur->val<x){
cur->r=insert(cur->r,x);
}
return cur;
}
bsTree treeToList(bsTree cur){
if(cur->l!=
nullptr){
treeToList(cur->l);
}
if(last==
nullptr){
last=cur;
fi=cur;
}
else{
last->r=cur;
last=cur;
}
if(cur->r!=
nullptr){
treeToList(cur->r);
}
return fi;
}
void outTree(bsTree cur){
if(cur==
nullptr){
return;
}
outTree(cur->l);
printf(
"%d ",cur->val );
outTree(cur->r);
}
void outList(bsTree cur){
bsTree node = cur;
while(node!=
nullptr){
printf(
"%d ",node->val );
node=node->r;
}
}
int main(){
while(~
scanf(
"%d",&n)){
bsTree tree =
nullptr;
last=fi=
nullptr;
for(
int i=
1;i<=n;++i){
scanf(
"%d",&ar[i]);
tree=insert(tree,ar[i]);
}
outTree(tree);
printf(
"\n");
tree=treeToList(tree);
printf(
"%d\n",tree->val );
outList(tree);
printf(
"\n");
}
return 0;
}
二叉搜索树查找:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N =
1005;
const int INF =
0x3f3f3f3f;
const LL mod =
1000000007;
const double eps =
1e-8;
struct BinaryTree{
int val;
int l;
int r;
BinaryTree(){val=
0;l=r=-
1;}
}tree[N];
int ar[N],n,tot;
int flag;
void build(
int k){
if(k>n)
return;
tree[++tot].val=ar[k];
tree[tot].l=tree[tot].r=-
1;
int i=
1;
while(
1){
if(ar[k]<tree[i].val){
if(tree[i].l!=-
1){
i=tree[i].l;
}
else{
tree[i].l=tot;
break;
}
}
else {
if(tree[i].r!=-
1){
i=tree[i].r;
}
else{
tree[i].r=tot;
break;
}
}
}
build(k+
1);
return;
}
void fin(
int x,
int cur){
if(x==tree[cur].val){
flag=
1;
return;
}
else if(x<tree[cur].val){
fin(x,tree[cur].l);
}
else fin(x,tree[cur].r);
}
int main(){
while(~
scanf(
"%d",&n)){
for(
int i=
1;i<=n;++i){
scanf(
"%d",&ar[i]);
}
tot=
1;
tree[
1].val=ar[
1];
tree[
1].l=tree[
1].r=-
1;
build(
2);
int x;
flag=
0;
scanf(
"%d",&x);
fin(x,
1);
if(flag==
1)
printf(
"Yes\n");
else printf(
"No\n");
}
return 0;
}
哈夫曼树:
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<map>
using namespace std;
const int Max=
1e6+
5;
map<int ,int> mp;
int l1,l2;
struct node
{
int date,lson,rson,par,flag;
string ans;
int cnt;
};
node p[Max];
int w[Max];
bool cmp(node a,node b)
{
return a.date<b.date;
}
void init(
int n)
{
for(
int i=
0;i<
2*n-
1;i++){
p[i].date=
0x3f3f3f3f;
p[i].flag=
0;
p[i].par=p[i].lson=p[i].rson=-
1;
}
}
void select(
int n)
{
sort(p,p+n,cmp);
for(
int i=
0;i<n;i++)
if(!p[i].flag){
l1=i,l2=i+
1;
p[i].flag=
1,p[i+
1].flag=
1;
break;
}
}
void HuffMan(
int n)
{
init(n);
for(
int i=
0;i<n;i++)
p[i].date=w[i];
for(
int i=n;i<
2*n-
1;i++){
select(i);
p[i].date=p[l1].date+p[l2].date;
p[i].lson=l1,p[i].rson=l2;
p[l1].par=i,p[l2].par=i;
}
}
void print(
int n)
{
for(
int i=
0;i<
2*n-
1;i++){
mp[p[i].date]=i;
cout<<i<<
" "<<p[i].date<<
" "<<p[i].par<<
" "<<p[i].lson<<
" "<<p[i].rson<<endl;
}
}
void bfs(
int n)
{
queue<node> que;
que.push(p[n]);
node q;
while(!que.empty()){
q=que.front();
que.pop();
if(q.lson!=-
1){
p[q.lson].ans=q.ans+
'0';
que.push(p[q.lson]);
}
if(q.rson!=-
1){
p[q.rson].ans=q.ans+
'1';
que.push(p[q.rson]);
}
}
}
int main()
{
int n,x;
cin>>n;
for(
int i=
0;i<n;i++)
cin>>w[i];
HuffMan(n);
print(n);
bfs(
2*n-
2);
while(
cin>>x)
cout<<p[mp[x]].ans<<endl;
}