2014河南省分析数据库的考试题目入门

  • 格式:docx
  • 大小:23.87 KB
  • 文档页数:6

1、请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺序连成一个单链表,表头指针为head。

二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。

分析你的算法的时、空复杂度。

2、#define maxsize 栈空间容量void InOutS(int s[maxsize])//s是元素为整数的栈,本算法进行入栈和退栈操作。

{int top=0; //top为栈顶指针,定义top=0时为栈空。

for(i=1; i<=n; i++) //n个整数序列作处理。

{scanf(“%d”,&x); //从键盘读入整数序列。

if(x!=-1) // 读入的整数不等于-1时入栈。

if(top==maxsize-1){printf(“栈满\n”);exit(0);}else s[++top]=x; //x入栈。

else //读入的整数等于-1时退栈。

{if(top==0){printf(“栈空\n”);exit(0);}else printf(“出栈元素是%d\n”,s[top--]);}}}//算法结3、后序遍历最后访问根结点,即在递归算法中,根是压在栈底的。

采用后序非递归算法,栈中存放二叉树结点的指针,当访问到某结点时,栈中所有元素均为该结点的祖先。

本题要找p和q 的最近共同祖先结点r ,不失一般性,设p在q的左边。

后序遍历必然先遍历到结点p,栈中元素均为p的祖先。

将栈拷入另一辅助栈中。

再继续遍历到结点q时,将栈中元素从栈顶开始逐个到辅助栈中去匹配,第一个匹配(即相等)的元素就是结点p 和q的最近公共祖先。

typedef struct{BiTree t;int tag;//tag=0 表示结点的左子女已被访问,tag=1表示结点的右子女已被访问}stack;stack s[],s1[];//栈,容量够大BiTree Ancestor(BiTree ROOT,p,q,r)//求二叉树上结点p和q的最近的共同祖先结点r。

{top=0; bt=ROOT;while(bt!=null ||top>0){while(bt!=null && bt!=p && bt!=q) //结点入栈{s[++top].t=bt; s[top].tag=0; bt=bt->lchild;} //沿左分枝向下if(bt==p) //不失一般性,假定p在q的左侧,遇结点p时,栈中元素均为p的祖先结点{for(i=1;i<=top;i++) s1[i]=s[i]; top1=top; }//将栈s的元素转入辅助栈s1 保存if(bt==q) //找到q 结点。

for(i=top;i>0;i--)//;将栈中元素的树结点到s1去匹配{pp=s[i].t;for (j=top1;j>0;j--)if(s1[j].t==pp) {printf(“p 和q的最近共同的祖先已找到”);return (pp);}}while(top!=0 && s[top].tag==1) top--; //退栈if (top!=0){s[top].tag=1;bt=s[top].t->rchild;} //沿右分枝向下遍历}//结束while(bt!=null ||top>0)return(null);//q、p无公共祖先}//结束Ancestor4、设计一个尽可能的高效算法输出单链表的倒数第K个元素。

5、请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺序连成一个单链表,表头指针为head。

二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。

分析你的算法的时、空复杂度。

6、约瑟夫环问题(Josephus问题)是指编号为1、2、…,n的n(n>0)个人按顺时针方向围坐成一圈,现从第s个人开始按顺时针方向报数,数到第m个人出列,然后从出列的下一个人重新开始报数,数到第m的人又出列,…,如此重复直到所有的人全部出列为止。

现要求采用循环链表结构设计一个算法,模拟此过程。

#include<stdlib.h>typedef int datatype;typedef struct node{datatype data;struct node *next;}listnode;typedef listnode *linklist;void jose(linklist head,int s,int m){linklist k1,pre,p;int count=1;pre=NULL;k1=head; /*k1为报数的起点*/while (count!=s) /*找初始报数起点*/{pre=k1;k1=k1->next;count++;}while(k1->next!=k1) /*当循环链表中的结点个数大于1时*/{ p=k1; /*从k1开始报数*/count=1;while (count!=m) /*连续数m个结点*/{ pre=p;p=p->next;count++;}pre->next=p->next; /*输出该结点,并删除该结点*/printf("%4d",p->data);free(p);k1=pre->next; /*新的报数起点*/}printf("%4d",k1->data); /*输出最后一个结点*/free(k1);}main(){linklist head,p,r;int n,s,m,i;printf("n=");scanf("%d",&n);printf("s=");scanf("%d",&s);printf("m=",&m);scanf("%d",&m);if (n<1) printf("n<0");else{/*建表*/head=(linklist)malloc(sizeof(listnode)); /*建第一个结点*/head->data=n;r=head;for (i=n-1;i>0;i--) /*建立剩余n-1个结点*/{ p=(linklist)malloc(sizeof(listnode));p->data=i;p->next=head;head=p;}r->next=head; /*生成循环链表*/jose(head,s,m); /*调用函数*/}}7、我们可用“破圈法”求解带权连通无向图的一棵最小代价生成树。

所谓“破圈法”就是“任取一圈,去掉圈上权最大的边”,反复执行这一步骤,直到没有圈为止。

请给出用“破圈法”求解给定的带权连通无向图的一棵最小代价生成树的详细算法,并用程序实现你所给出的算法。

注:圈就是回路。

8、由二叉树的前序遍历和中序遍历序列能确定唯一的一棵二叉树,下面程序的作用是实现由已知某二叉树的前序遍历和中序遍历序列,生成一棵用二叉链表表示的二叉树并打印出后序遍历序列,请写出程序所缺的语句。

#define MAX 100typedef struct Node{char info; struct Node *llink, *rlink; }TNODE;char pred[MAX],inod[MAX];main(int argc,int **argv){ TNODE *root;if(argc<3) exit 0;strcpy(pred,argv[1]); strcpy(inod,argv[2]);root=restore(pred,inod,strlen(pred));postorder(root);}TNODE *restore(char *ppos,char *ipos,int n){ TNODE *ptr; char *rpos; int k;if(n<=0) return NULL;ptr->info=(1)_______;for((2)_______ ; rpos<ipos+n;rpos++) if(*rpos==*ppos) break;k=(3)_______;ptr->llink=restore(ppos+1, (4)_______,k );ptr->rlink=restore ((5)_______+k,rpos+1,n-1-k);return ptr;}postorder(TNODE*ptr){ if(ptr=NULL) return;postorder(ptr->llink); postorder(ptr->rlink); printf(“%c”,ptr->info); }9、矩阵中元素按行和按列都已排序,要求查找时间复杂度为O(m+n),因此不能采用常规的二层循环的查找。

可以先从右上角(i=a,j=d)元素与x比较,只有三种情况:一是A[i,j]>x,这情况下向j 小的方向继续查找;二是A[i,j]<x,下步应向i大的方向查找;三是A[i,j]=x,查找成功。

否则,若下标已超出范围,则查找失败。

void search(datatype A[ ][ ], int a,b,c,d, datatype x)//n*m矩阵A,行下标从a到b,列下标从c到d,本算法查找x是否在矩阵A中.{i=a; j=d; flag=0; //flag是成功查到x的标志while(i<=b && j>=c)if(A[i][j]==x) {flag=1;break;}else if (A[i][j]>x) j--; else i++;if(flag) printf(“A[%d][%d]=%d”,i,j,x); //假定x为整型.else printf(“矩阵A中无%d 元素”,x);}算法search结束。

[算法讨论]算法中查找x的路线从右上角开始,向下(当x>A[i,j])或向左(当x<A[i,j])。

向下最多是m,向左最多是n。

最佳情况是在右上角比较一次成功,最差是在左下角(A[b,c]),比较m+n次,故算法最差时间复杂度是O(m+n)。

10、请设计一个算法,要求该算法把二叉树的叶子结点按从左到右的顺序连成一个单链表,表头指针为head。

二叉树按二叉链表方式存储,链接时用叶子结点的右指针域来存放单链表指针。