目录
1.已知一颗二叉树按顺序存储结构进行存储,设计一个算法,求编号分别为i和j的两个节点的最近的公共祖先节点的值。
4.假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度。
5.设一颗二叉树中各个节点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个一维数组A[1...n]和B[1...n]中,试编写算法建立该二叉树的二叉链表。
6.二叉树按二叉链表形式存储,写一个判别给定二叉树是否是完全二叉树的算法。
7.假设二叉树采用二叉链表存储结构存储,试着设计一个算法,计算一颗给定二叉树的所有双分支节点的个数。
8.设树B是一颗采用链式结构存储的二叉树,编写一个把树B中所有节点的左,右子树进行交换的函数。
1.已知一颗二叉树按顺序存储结构进行存储,设计一个算法,求编号分别为i和j的两个节点的最近的公共祖先节点的值。
#include <stdio.h>
#include <malloc.h>
#define MaxSize 13
typedef struct TNode
{
char data;
TNode* lchild;
TNode* rchild;
}TNode;
int find_public(TNode T[],int i,int j)//注意这里不是TNode* &T
{
if(T[i].data!='#'&&T[j].data!='#')//还要判断结点是否存在
{
while(i!=j)
{
if(i>j)
i=i/2;
else
j=j/2;
}
return i;
}
else
return 0;
}
int main()
{
TNode T[MaxSize];
for(int i=1;i<MaxSize;i++)//从数组下标1开始存储
{
char c;
scanf("%c",&c);
T[i].data=c;
}
int k=find_public(T,4,10);
printf("%c\n",T[k].data);//测试数据:ABCDE####F#,输出data:B
return 0;
}
/*
A
B C
D E
F
*/
2.编写后序遍历的二叉树的非递归算法
//非递归的一个后序遍历二叉树
#include<iostream>
using namespace std;
typedef struct TreeNode{
char data;
struct TreeNode *lchild,*rchild;
int tag;
}TreeNode,*Tree;
void creattree(Tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(TreeNode *)malloc(sizeof(TreeNode));
t->data=ch;
t->tag=0;
t->lchild=NULL;
t->rchild=NULL;
creattree(t->lchild);
creattree(t->rchild);
}
}
void back(Tree t)
{
struct TreeNode *stack[100];
int top=-1;
TreeNode *p=t;
TreeNode *x;
while(p||top!=-1)
{
if(p)
{
top++;
stack[top]=p;
p=p->lchild;
}
else
{
p=stack[top];
if(p->rchild&&p->rchild->tag==0)
p=p->rchild;
else
{
p=stack[top];
top--;
cout<<p->data<<" ";
p->tag=1;
p=NULL;
}
}
}
}
int main()
{
Tree t;
creattree(t);
back(t);
return 0;
}
//ABDEC
//测试:ABD##E##C##
3.试给出二叉树的自下而上,从右到左的层次遍历算法。
#include<iostream>
using namespace std;
#define Max 10
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
void buildtree(tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(treenode *)malloc(sizeof(treenode));
t->data=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild);
}
}
typedef struct stack1{
struct treenode *data[Max];
int top;
}stack1;
bool isempty(stack1 s)
{
if(s.top==-1) return true;
return false;
}
bool isfull(stack1 s)
{
if(s.top==Max-1) return true;
return false;
}
bool enters(stack1 &s,treenode *p)
{
if(isfull(s))
{
cout<<"栈满"<<endl;
return false;
}
s.data[++s.top]=p;
return true;
}
bool outs(stack1 &s,treenode *&p)
{
if(isempty(s))
{
cout<<"栈空"<<endl;
return false;
}
p=s.data[s.top--];
return true;
}
struct squeue1{
struct treenode *data[Max];
int f,r,tag;
};
bool entersqueue(squeue1 &s,treenode *x)
{
if(s.f==s.r&&s.tag==1)
{
cout<<"队满"<<endl;
return false;
}
s.data[s.r]=x;
s.r=(s.r+1)%Max;
s.tag=1;
return true;
}
int outsqueue(squeue1 &s,treenode *&x)
{
if(s.f==s.r&&s.tag==0)
{
cout<<"队空"<<endl;
return 0;
}
x=s.data[s.f];
s.f=(s.f+1)%Max;
s.tag=0;
return 1;
}
void solve(tree t)
{
stack1 s;
squeue1 q;
treenode *p;
if(t)
{
s.top=-1;
q.f=q.r=q.tag=0;
entersqueue(q,t);
while(!(q.f==q.r&&q.tag==0))
{
outsqueue(q,p);
enters(s,p);
if(p->lchild) entersqueue(q,p->lchild);
if(p->rchild) entersqueue(q,p->rchild);
}
while(!isempty(s))
{
outs(s,p);
cout<<p->data<<" ";
}
}
}
int main()
{
tree t;
buildtree(t);
solve(t);
return 0;
}
//测试数据:ABD##E##CF##G##
4.假设二叉树采用二叉链表存储结构,设计一个非递归算法求二叉树的高度。
//非递归计算二叉树的高度
#include<iostream>
using namespace std;
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
void buildtree(tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(treenode *)malloc(sizeof(treenode));
t->data=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild);
}
}
int dept(tree t)
{
if(!t) return 0;
tree q[10];
int f=-1,r=-1;
int L=0,ans=0;
q[++r]=t;
tree p;
while(f<r)
{
p=q[++f];
if(p->lchild) q[++r]=p->lchild;
if(p->rchild) q[++r]=p->rchild;
if(f==L)
{
ans++;
L=r;
}
}
return ans;
}
int main()
{
tree t;
buildtree(t);
cout<<"树的高度为:"<<dept(t)<<endl;
return 0;
}
//测试数据:ABD##E##CF###
5.设一颗二叉树中各个节点的值互不相同,其先序遍历序列和中序遍历序列分别存于两个一维数组A[1...n]和B[1...n]中,试编写算法建立该二叉树的二叉链表。
//中序先序构造二叉树
#include<iostream>
using namespace std;
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
int pos=0;
tree build(char a[],char b[],int s,int e)
{
if(s<=e)
{
treenode *root=(treenode *)malloc(sizeof(treenode));
root->data=a[pos];
int i;
for(i=s;i<=e;i++) if(b[i]==root->data) break;
pos++;
root->lchild=build(a,b,s,i-1);
root->rchild=build(a,b,i+1,e);
return root;
}
return NULL;
}
void disp(tree t)
{
if(t)
{
disp(t->lchild);
disp(t->rchild);
cout<<t->data<<" ";
}
}
int main() {
char a[]={'A','B','D','E','C','F'};//先序序列
char b[]={'D','B','E','A','F','C'};//中序序列
tree root=build(a,b,0,5);
cout<<"后序序列为:"<<endl;
disp(root);
return 0;
}
/* A
/ \
B C
/ \ /
D E F
*/
6.二叉树按二叉链表形式存储,写一个判别给定二叉树是否是完全二叉树的算法。
//判断是否是完全二叉树
#include<iostream>
using namespace std;
#define Max 15
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
void buildtree(tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(treenode *)malloc(sizeof(treenode));
t->data=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild);
}
}
struct squeue{
struct treenode *data[Max];
int f,r,tag;
};
bool isempty(squeue s)
{
if(s.f==s.r&&s.tag==0) return true;
return false;
}
bool isfull(squeue s)
{
if(s.f==s.r&&s.tag==1) return true;
return false;
}
bool enters(squeue &s,treenode *p)
{
if(isfull(s)) return false;
s.data[s.r]=p;
s.r=(s.r+1)%Max;
s.tag=1;
return true;
}
bool outs(squeue &s,treenode *&p)
{
if(s.f==s.r&&s.tag==0) return false;
p=s.data[s.f];
s.f=(s.f+1)%Max;
s.tag=0;
return true;
}
bool isok(tree t)
{
squeue s;
s.f=s.r=s.tag=0;
bool flag=true,ans=true;
if(t==NULL) ans=true;
if(!t->lchild&&!t->rchild) ans=true;
enters(s,t);
treenode *p;
while(!isempty(s))
{
outs(s,p);
if(!p->lchild)
{
flag=false;
if(p->rchild) ans=false;
}
else//有左孩子
{
if(flag)//之前不存在缺孩子的节点
{
enters(s,p->lchild);
if(p->rchild) enters(s,p->rchild);
else flag=false;
}
else//之前存在缺孩子的节点
ans=false;
}
}
if(ans) return true;
return false;
}
int main()
{
tree t;
buildtree(t);
if(isok(t)) cout<<"yes"<<endl;
else cout<<"no"<<endl;
return 0;
}
//ABD##E##CF##G## 完全
//ABD###CE##F## 非完全
7.假设二叉树采用二叉链表存储结构存储,试着设计一个算法,计算一颗给定二叉树的所有双分支节点的个数。
//计算二叉树中双分支结点的个数
#include<iostream>
using namespace std;
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
void buildtree(tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(treenode *)malloc(sizeof(treenode));
t->data=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild);
}
}
int num(tree t)
{
if(!t) return 0;
else if(t->lchild&&t->rchild) return num(t->lchild)+num(t->rchild)+1;
else return num(t->lchild)+num(t->rchild);
}
int main()
{
tree t;
buildtree(t);
cout<<"该二叉树中双分结点有 "<<num(t)<<" 个"<<endl;
return 0;
}
/*
A
/ \
B C
/\ / \
D E F G
*/
//前序序列:ABD##E##CF##G##
8.设树B是一颗采用链式结构存储的二叉树,编写一个把树B中所有节点的左,右子树进行交换的函数。
//交换左右子树
#include<iostream>
using namespace std;
typedef struct treenode{
char data;
struct treenode *lchild,*rchild;
}treenode,*tree;
void buildtree(tree &t)
{
char ch;
ch=getchar();
if(ch=='#') t=NULL;
else
{
t=(treenode *)malloc(sizeof(treenode));
t->data=ch;
t->lchild=NULL;
t->rchild=NULL;
buildtree(t->lchild);
buildtree(t->rchild);
}
}
void swap(tree &t)
{
treenode *p;
if(t)
{
swap(t->lchild);
swap(t->rchild);
p=t->lchild;
t->lchild=t->rchild;
t->rchild=p;
}
}
void disp(tree t)
{
if(t)
{
cout<<t->data<<" ";
disp(t->lchild);
disp(t->rchild);
}
}
int main()
{
tree t;
buildtree(t);
cout<<"交换过后的二叉树为(前序序列):"<<endl;
swap(t);
disp(t);
return 0;
}
/*
A A
B C C B
D E F G G F E D
ABD##E##CF##G## ACGFBED
*/