您的位置:首页 > 理论基础 > 数据结构算法

广工anyview数据结构-07~08(乱码不贴)

2015-07-10 11:52 666 查看
/**********

【题目】试编写如下定义的递归函数的递归算法:

g(m,n) = 0 当m=0,n>=0

g(m,n) = g(m-1,2n)+n 当m>0,n>=0

**********/

int G(int m, int n)

/* 如果 m<0 或 n<0 则返回 -1 */

{

if(m<0||n<0) return -1;

if(m==0&&n==0) return 0;

if(m>0&&n>=0) return G(m-1,2*n)+n;

}

/**********

【题目】试写出求递归函数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);

}

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: