}
/**********
【题目】试写出求递归函数F(n)的递归算法:
F(n) = n+1 当n=0
F(n) = nF(n/2) 当n>0
**********/
int F(int n)
/* 如果 n<0 则返回 -1 */
{
if(n==0) return 1;
else if(n<0) return -1;
else if(n>0) return F(n/2)*n;
}
/**********
【题目】求解平方根 的迭代函数定义如下:
sqrt(A,p,e) = p 当|p*p-A|<e
sqrt(A,p,e) = sqrt(A,(p+A/p)/2,e) 当|p*p-A|>=e
其中,p是A的近似平方根,e是结果允许误差。试写出相
应的递归算法。
**********/
float Sqrt(float A, float p, float e)
{
if(-e<p*p-A&&p*p-A<e) return p;
else return Sqrt(A,(p+A/p)/2,e);
}
/**********
【题目】已知Ackerman函数的定义如下:
akm(m,n) = n+1 当m=0
akm(m,n) = akm(m-1,1) 当m!=0,n=0
akm(m,n) = akm(m-1,akm(m,n-1)) 当m!=0,n!=0
请写出递归算法。
**********/
int Akm(int m, int n)
/* 若 m<0 或 n<0 则返回-1 */
{
if(m<0||n<0)return -1;
else if(m==0)return n+1;
else if(m!=0&&n==0)return Akm(m-1,1);
else if(m!=0&&n!=0)return Akm(m-1,Akm(m,n-1)) ;
}
/**********
【题目】试写出求递归函数F(n)的非递归算法:
F(n) = n+1 当n=0
F(n) = nF(n/2) 当n>0
**********/
int F(int n)
/* 如果 n<0 则返回 -1 */
{
if(n<0)return -1;
else if(n==0)return 1;
else return n*F(n/2);
}
/**********
【题目】求解平方根 的迭代函数定义如下:
sqrt(A,p,e) = p 当|p*p-A|<e
sqrt(A,p,e) = sqrt(A,(p+A/p)/2,e) 当|p*p-A|>=e
其中,p是A的近似平方根,e是结果允许误差。试写出相
应的非递归算法。
**********/
float Sqrt(float A, float p, float e)
{
if(-e<p*p-A&&p*p-A<e) return p;
else return Sqrt(A,(p+A/p)/2,e);
}
/**********
【题目】假设以二维数组g[1..m][1..n]表示一个图像
区域,g[i][j]表示该区域中点(i,j)所具颜色,其值
为从0到k的整数。试编写递归算法,将点(i0,j0)所在
区域的颜色置换为颜色c。约定与(i0,j0)同色的上、
下、左、右的邻接点为同色区域的点。
表示图像区域的类型定义如下:
typedef char GTYPE[m+1][n+1];
**********/
void ChangeColor(GTYPE g, int m, int n,
char c, int i0, int j0)
/* 在g[1..m][1..n]中,将元素g[i0][j0] */
/* 所在的同色区域的颜色置换为颜色c */
{
char color=g[i0][j0];
g[i0][j0]=c;
if(i0-1>=1&&g[i0-1][j0]==color)
ChangeColor(g,m,n,c,i0-1,j0);
if(j0-1>=1&&g[i0][j0-1]==color)
ChangeColor(g,m,n,c,i0,j0-1);
if(i0+1<=m&&g[i0+1][j0]==color)
ChangeColor(g,m,n,c,i0+1,j0);
if(j0+1<=n&&g[i0][j0+1]==color)
ChangeColor(g,m,n,c,i0,j0+1);
}
/**********
【题目】若两棵二叉树T1和T2皆为空,或者皆不空
且T1的左、右子树和T2的左、右子树分别相似,则
称二叉树T1和T2相似。试编写算法,判别给定两棵
二叉树是否相似。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
Status Similar(BiTree T1, BiTree T2)
/* 判断两棵二叉树是否相似的递归算法 */
{
if(!T1&&!T2)return TRUE;
else if(T1&&T2&&Similar(T1->lchild,T2->lchild)&&Similar(T1->rchild,T2->rchild)) return TRUE;
else return FALSE;
}
/**********
【题目】编写递归算法,求对二叉树T先序遍历时
第k个访问的结点的值。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int countNodes(BiTree bt){
return bt?(1 + countNodes(bt->lchild)+countNodes(bt->rchild)):0;
}
TElemType PreOrderK(BiTree T, int k)
/* 求对二叉树T先序遍历时第k个访问的结点的值。*/
/* 若失败,则返回'#' */
{
int count;
if(k <=0||!T) return '#';
if(k==1) return T->data;
count=countNodes(T->lchild);
return count>=--k?PreOrderK(T->lchild,k):PreOrderK(T->rchild,k-count);
}
/**********
【题目】编写递归算法,计算二叉树T中叶子结点的数目。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int Leaves(BiTree T)
/* 计算二叉树T中叶子结点的数目 */
{
if(NULL==T) return 0;
if(NULL == T->lchild && NULL == T->rchild ) return 1;
return Leaves(T->lchild)+Leaves(T->rchild);
}
/**********
【题目】试利用栈及其基本操作写出二叉树T的非递归
的先序遍历算法。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef BiTree SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
**********/
void PreOrder(BiTree T, void (*visit)(TElemType))
/* 使用栈,非递归先序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
Stack S;
BiTree p;
if(!T)return;
InitStack(S);
do{
visit(T->data);
if(!T->lchild&&!T->rchild){
while(!StackEmpty(S)){
if(GetTop(S,p)&&p->rchild&&p->rchild!=T)
{T=p->rchild;break;}
Pop(S,T);
}
}
else {
Push(S,T);
T=(T->lchild)?T->lchild:T->rchild;}
}while(!StackEmpty(S));
}
/**********
【题目】试利用栈及其基本操作写出二叉树T的非递归
的后序遍历算法(提示:为分辨后序遍历时两次进栈的
不同返回点,需在指针进栈时同时将一个标志进栈)。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef struct {
struct BiTNode *ptr; // 二叉树结点的指针类型
int tag; // 0..1
} SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
**********/
void PostOrder(BiTree T, void (*visit)(TElemType))
/* 使用栈,非递归后序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
Stack S;
InitStack(S);
SElemType e;
BiTree p=T;
int tag=0;
if(T){
e.tag=0;
while(!StackEmpty(S)||p==T){
while(p&&!tag){
e.ptr=p;
if(p->lchild){
p=p->lchild;
e.tag=0;
}
else{
p=p->rchild;
e.tag=1;
}
Push(S,e);
}//while
GetTop(S,e);
if(!StackEmpty(S)&&e.tag){
Pop(S,e);
p=e.ptr;
visit(p->data);
}
if(!StackEmpty(S)){
Pop(S,e);
p=e.ptr;
if(e.tag){
visit(p->data);
p=NULL;
}
else{
if(p->rchild){
p=p->rchild;
tag=0;
e.tag=1;
Push(S,e);
}
else{
visit(p->data);
p=NULL;
}
}
}
else{
p=NULL;
}
}
}
}
/**********
【题目】二叉树采用三叉链表的存储结构,试编写
不借助栈的非递归中序遍历算法。
三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *parent, *lchild, *rchild;
} TriTNode, *TriTree;
**********/
void InOrder(TriTree PT, void (*visit)(TElemType))
/* 不使用栈,非递归中序遍历二叉树PT, */
/* 对每个结点的元素域data调用函数visit */
{
TriTNode *p;
p=PT;
while(p->lchild) p=p->lchild;
while(p){
visit(p->data);
if(p->rchild){
p=p->rchild;
while(p->lchild) p=p->lchild;
}
else if(p->parent->lchild==p) p=p->parent;
else
{
p=p->parent;
while(p->parent&&p->parent->rchild==p)
p=p->parent;
p=p->parent;
}
}
}
/**********
【题目】假设在三叉链表的结点中增设一个标志域
(mark取值0,1或2)以区分在遍历过程中到达该结点
时应继续向左或向右或访问该结点。试以此存储结
构编写不用栈辅助的二叉树非递归后序遍历算法。
带标志域的三叉链表类型定义:
typedef struct TriTNode {
TElemType data;
struct TriTNode *lchild, *rchild, *parent;
int mark; // 标志域
} TriTNode, *TriTree;
**********/
void PostOrder(TriTree T, void (*visit)(TElemType))
/* 不使用栈,非递归后序遍历二叉树T, */
/* 对每个结点的元素域data调用函数visit */
{
TriTree p;
p=T;
while(p){
while(p->mark==0){
p->mark=1;
if(p->lchild)
p=p->lchild;
}
while(p->mark==1){
p->mark=2;
if(p->rchild)
p=p->rchild;
}
if(p->mark==2){
visit(p->data);
p=p->parent;
}
}
}
/**********
【题目】编写递归算法,将二叉树中所有结点的
左、右子树相互交换。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void ExchangeSubTree(BiTree &T)
/* 将二叉树中所有结点的左、右子树相互交换 */
{
if (T == NULL) return;
BiTree pn = T->lchild;
T->lchild = T->rchild;
T->rchild = pn;
ExchangeSubTree(T->lchild);
ExchangeSubTree(T->rchild);
}
/**********
【题目】编写递归算法:求二叉树中以元素值
为x的结点为根的子树的深度。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
int GetDepth(BiTree bt)//求树的深度子函数
{
int m,n; //记录返回的个数
if(bt) //非空执行
{
m=GetDepth(bt->lchild); //对左子树递归
n=GetDepth(bt->rchild); //对右子树递归
return (m>=n?m+1:n+1); //返回最深的度数
}
else //bt空,返回0
return 0;
}
int Depthx(BiTree T, TElemType x)
/* 求二叉树中以值为x的结点为根的子树深度 */
{
int m,n;
if(!T) //空,返回0
return 0;
if(T->data==x) //找到T,求T的深度
return GetDepth(T); //返回T的深夜
else
{
if(T->lchild) //向左子树找T
m=Depthx(T->lchild,x);
if(T->rchild) //向右子树找T
n=Depthx(T->rchild,x);
}
return (m>=n?m:n); //返回向下递归的最大深度
}
/**********
【题目】编写递归算法:对于二叉树中每一个元素值为x
的结点,删去以它为根的子树,并释放相应的空间。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void DelTree(BiTree bt, TElemType x)
{
if(bt)
{if(bt->lchild&&bt->lchild->data==x)
{free(bt->lchild);
bt->lchild=NULL;
}
if(bt->rchild&&bt->rchild->data==x)
{free(bt->rchild);
bt->rchild=NULL;
}
DelTree(bt->lchild,x);
DelTree(bt->rchild,x);
}
}
void ReleaseX(BiTree &T, char x)
/* 对于二叉树T中每一个元素值为x的结点, */
/* 删去以它为根的子树,并释放相应的空间 */
{
if(T!= NULL&&T->data==x)
{free(T);T=NULL;}
else DelTree(T,x);
}
/**********
【题目】编写复制一棵二叉树的递归算法。
二叉链表类型定义:
typedef char TElemType; // 设二叉树的元素为char类型
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
**********/
void CopyBiTree(BiTree T, BiTree &TT)
/* 递归复制二叉树T得到TT */
{
BiTree lptr,rptr;
if (!T) T=NULL;
else{
CopyBiTree(T->lchild,lptr);
CopyBiTree(T->rchild,rptr);
TT=(BiTree)malloc(sizeof(BiTNode));
TT->data=T->data;
TT->lchild=lptr;TT->rchild=rptr;
}
}
/**********
【题目】编写算法判别给定二叉树是否为完全二叉树。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild, *rchild;
} BiTNode, *BiTree;
可用队列类型Queue的相关定义:
typedef BiTree QElemType; // 设队列元素为二叉树的指针类型
Status InitQueue(Queue &Q);
Status EnQueue(Queue &Q, QElemType e);
Status DeQueue(Queue &Q, QElemType &e);
Status GetHead(Queue Q, QElemType &e);
Status QueueEmpty(Queue Q);
**********/
Status CompleteBiTree(BiTree T)
/* 判别二叉树T是否为完全二叉树 */
{
int flag=0,top=0;
BiTree stack[100];
Queue Q;
BiTree p;
InitQueue(Q);
if(T){
EnQueue(Q,T);
while(!QueueEmpty(Q)){
DeQueue(Q,p);
if(p){
EnQueue(Q,p->lchild);
EnQueue(Q,p->rchild);
stack[top++]=p->lchild;
stack[top++]=p->rchild;
}
}//while
while(top){
if(flag){
if(stack[--top]==NULL)
return FALSE;
}
else{
if(stack[--top]!=NULL){//遇到第一个非NULL结点
flag=1;
}
}
}
}//if
return TRUE;
}
/**********
【题目】试编写一个二叉排序树的判定算法。
二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BiTNode {
TElemType data;
struct BSTNode *lchild, *rchild;
}BSTNode, *BSTree;
**********/
Status IsBSTree(BSTree T)
/* 判别二叉树T是否为二叉排序树。*/
/* 若是,则返回TRUE,否则FALSE */
{
KeyType k;
if(T==NULL)return TRUE;
k=T->data.key;
if(T->lchild==NULL&&T->rchild==NULL)return TRUE;
if(T->lchild!=NULL&&T->rchild!=NULL)
{
if(k>T->lchild->data.key&&k<T->rchild->data.key)
if(IsBSTree(T->lchild)&&IsBSTree(T->rchild))
return TRUE;
return FALSE;
}
if(T->lchild!=NULL&&k>T->lchild->data.key)
if(IsBSTree(T->lchild))return TRUE;
if(T->rchild!=NULL&&k<T->rchild->data.key)
if(IsBSTree(T->rchild))return TRUE;
return FALSE;
}
/**********
【题目】编写递归算法,从大到小输出给定二叉排序树
中所有关键字不小于x的数据元素。
二叉排序树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
}BSTNode, *BSTree;
**********/
void OrderOut(BSTree T, KeyType k, void(*visit)(TElemType))
/* 调用visit(T->data)输出 */
{
KeyType key = T->data.key;
if(!T)return;
if(key>=k)
{
OrderOut(T->rchild,k,visit);
visit(T->data);
OrderOut(T->lchild,k,visit);
}
else{ OrderOut(T->rchild,k,visit);}
}
/**********
【题目】试写一非递归算法,在二叉查找树T中插入元素e。
二叉查找树的类型BSTree定义如下:
typedef struct {
KeyType key;
... ... // 其他数据域
} TElemType;
typedef struct BSTNode {
TElemType data;
struct BSTNode *lchild,*rchild;
} BSTNode, *BSTree;
**********/
Status InsertBST_I(BSTree &T, TElemType k)
/* 在二叉查找树T中插入元素e的非递归算法 */
{
BSTree q,s,p=T;
q=(BSTNode *)malloc(sizeof(BSTNode));
if(NULL==q)return OVERFLOW;
q->data.key=k.key;
q->lchild=q->rchild=NULL;
while(p){
if(p->data.key==k.key)return TRUE;
s=p;
p=(p->data.key>k.key)?p->lchild:p->rchild;
}
if(T==NULL)T=q;
else if(k.key<s->data.key)
s->lchild=q;
else s->rchild=q;
}
/**********
【题目】试编写算法,求二叉树T中结点a和b的最近共同祖先。
二叉链表类型定义:
typedef struct BiTNode {
TElemType data;
struct BiTNode *lchild,*rchild;
} BiTNode, *BiTree;
可用栈类型Stack的相关定义:
typedef struct {
BiTNode *ptr; // 二叉树结点的指针类型
int tag; // 0..1
} SElemType; // 栈的元素类型
Status InitStack(Stack &S);
Status StackEmpty(Stack S);
int StackLength(SqStack S);
Status Push(Stack &S, SElemType e);
Status Pop(Stack &S, SElemType &e);
Status GetTop(Stack S, SElemType &e);
**********/
//封装压栈方法
Status Push_c(BiTree T, Stack &S)
{
SElemType sElem;
sElem.ptr=T;
return Push(S,sElem);
}
//将到目标元素的最短路径存起来
Status collect(BiTree T, TElemType a, Stack &S)
{
if(NULL==T) return FALSE;
if(a==T->data) return Push_c(T,S);
else if(collect(T->lchild,a,S)) return Push_c(T,S);
else if(collect(T->rchild,a,S)) return Push_c(T,S);
else return FALSE;
}
//查找栈内时候有跟目标元素相同的元素
Status search(Stack S,BiTNode *t)
{
SElemType e;
while(!StackEmpty(S))
{
if(Pop(S,e))
if(e.ptr->data==t->data)
return TRUE;
}
return FALSE;
}
//将栈倒置
Stack reverse(Stack &S)
{
SElemType sE;
Stack t; InitStack(t);
while(!StackEmpty(S))
{
if(Pop(S,sE))
Push(t,sE);
}
return t;
}
//比较两个栈的元素,查找最近的两个相同的元素
BiTree Comn(BiTree T, TElemType a, TElemType b, Stack S_a, Stack S_b)
{
SElemType e;
S_b=reverse(S_b);
S_a=reverse(S_a);
while(!StackEmpty(S_a))
{
if(Pop(S_a,e)&&e.ptr->data!=b)
if(search(S_b,e.ptr))
return e.ptr;
}
return NULL;
}
BiTree CommAncestor(BiTree T, TElemType a, TElemType b)
/* 求二叉树T中结点a和b的最近共同祖先 */
{
Stack S_a,S_b;
BiTree biT;
int flag;
if(NULL==T) return NULL;
if(T->data==a||T->data==b) return NULL;//当a或b所在节点为根节点时,a和b没有共同的祖先
if(!InitStack(S_a)||!InitStack(S_b)) return NULL;
if(!collect(T,a,S_a)||!collect(T,b,S_b)) return NULL;
flag=StackLength(S_a)>StackLength(S_b)?1:0;//比较两个路径的长度,可能有利于提高查找效率,可行性待定
if(flag&&(biT=Comn(T,a,b,S_a,S_b))!=NULL) return biT;
else return Comn(T,b,a,S_b,S_a);
}
/**********
【题目】在平衡二叉排序树的每个结点中增设一个
lsize域,其值为该结点的左子树中的结点数加1。
试编写时间复杂度为O(logn)的算法,求树中第k小
的结点的位置。
平衡二叉查排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
struct BBSTNode *lchild,*rchild;
int bf; // 平衡因子
int lsize; // 新增域,值为左子树的结点数+1
} BBSTNode, *BBSTree;
**********/
BBSTNode *Ranking(BBSTree T, int k)
/* 在含lsize域的平衡二叉排序树T中,*/
/* 求指向T中第k小的结点的指针 */
{
if(k>T->lsize)
{
if(!T->rchild) return NULL;
return(Ranking(T->rchild,k-T->lsize));
}
else if(k<T->lsize)
return (Ranking(T->lchild,k));
return T;
}
/**********
【题目】假设二叉排序树T的每个结点的平衡因子域bf当前
均为0。试编写算法,求二叉排序树T的深度,并为每个结点
的bf域赋予正确的平衡因子值。
平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;
**********/
int Depth_BF(BBSTree T)
/* 求二叉排序树T的深度,并为每个结点 */
/* 的bf域赋予正确的平衡因子值。 */
{
int dl,dr,s;
if(NULL==T)return 0;
else{
dl=Depth_BF(T->lchild);
dr=Depth_BF(T->rchild);
T->bf=dl-dr;
s=dl>dr?dl:dr;
return 1+s;
}
}
/**********
【题目】编写平衡二叉排序树的右平衡处理算法。
平衡二叉排序树的类型BBSTree定义如下:
typedef char KeyType;
typedef struct BBSTNode {
KeyType key;
int bf; // 平衡因子
struct BBSTNode *lchild,*rchild;
} BBSTNode, *BBSTree;
可调用下列旋转调整操作:
void L_Rotate(BBSTree &p); // 对最小失衡子树p做左旋调整
void R_Rotate(BBSTree &p); // 对最小失衡子树p做右旋调整
**********/
void RightBalance(BBSTree &T)
/* 实现对二叉树T的右平衡处理 */
{
BBSTree rd,lc;
rd=T->rchild;
switch(rd->bf)
{
case RH:
T->bf=rd->bf=EH;
L_Rotate(T);
break;
case LH:
lc=rd->lchild;
switch(lc->bf)
{
case RH:T->bf=LH;rd->bf=EH;
break;
case EH:T->bf=rd->bf=EH;
break;
case LH:T->bf=EH;rd->bf=RH;
break;
}
lc->bf=EH;
R_Rotate(T->rchild);
L_Rotate(T);
}
}