2010海南省分析数据库的考试题目加强

1、编程实现单链表的就地逆置。

23.在数组 A[1..n]中有n个数据,试建立一个带有头结点的循环链表,头指针为h,要求链中数据从小到大排列,重复的数据在链中只保存一个.

2、若第n件物品能放入背包,则问题变为能否再从n-1件物品中选出若干件放入背包(这时背包可放入物品的重量变为s-w[n])。若第n件物品不能放入背包,则考虑从n-1件物品选若干件放入背包(这时背包可放入物品仍为s)。若最终s=0,则有一解;否则,若s<0或虽然s>0但物品数n<1,则无解。

(1)s-w[n],n-1 //Knap(s-w[n],n-1)=true

(2)s,n-1 // Knap←Knap(s,n-1)

3、有一种简单的排序算法,叫做计数排序(count sorting)。这种排序算法对一个待排序的表(用数组表示)进行排序,并将排序结果存放到另一个新的表中。必须注意的是,表中所有待排序的关键码互不相同,计数排序算法针对表中的每个记录,扫描待排序的表一趟,统计表中有多少个记录的关键码比该记录的关键码小,假设针对某一个记录,统计出的计数值为c,那么,这个记录在新的有序表中的合适的存放位置即为c。

(1) (3分)给出适用于计数排序的数据表定义;

(2) (7分)使用Pascal或C语言编写实现计数排序的算法;

(3) (4分)对于有n个记录的表,关键码比较次数是多少?

(4) (3分)与简单选择排序相比较,这种方法是否更好?为什么?

4、数组A和B的元素分别有序,欲将两数组合并到C数组,使C仍有序,应将A和B拷贝到C,只要注意A和B数组指针的使用,以及正确处理一数组读完数据后将另一数组余下元素复制到C中即可。

void union(int A[],B[],C[],m,n)

//整型数组A和B各有m和n个元素,前者递增有序,后者递减有序,本算法将A和B归并为递增有序的数组C。

{i=0; j=n-1; k=0;// i,j,k分别是数组A,B和C的下标,因用C描述,下标从0开始while(i=0)

if(a[i]

while(i

while(j>=0) c[k++]=b[j--];

}算法结束

4、要求二叉树按二叉链表形式存储。15分

(1)写一个建立二叉树的算法。(2)写一个判别给定的二叉树是否是完全二叉树的算法。BiTree Creat() //建立二叉树的二叉链表形式的存储结构

{ElemType x;BiTree bt;

scanf(“%d”,&x); //本题假定结点数据域为整型

if(x==0) bt=null;

else if(x>0)

{bt=(BiNode *)malloc(sizeof(BiNode));

bt->data=x; bt->lchild=creat(); bt->rchild=creat();

}

else error(“输入错误”);

return(bt);

}//结束 BiTree

int JudgeComplete(BiTree bt) //判断二叉树是否是完全二叉树,如是,返回1,否则,返回0

{int tag=0; BiTree p=bt, Q[]; // Q是队列,元素是二叉树结点指针,容量足够大

if(p==null) return (1);

QueueInit(Q); QueueIn(Q,p); //初始化队列,根结点指针入队

while (!QueueEmpty(Q))

{p=QueueOut(Q); //出队

if (p->lchild && !tag) QueueIn(Q,p->lchild); //左子女入队

else {if (p->lchild) return 0; //前边已有结点为空,本结点不空

else tag=1; //首次出现结点为空

if (p->rchild && !tag) QueueIn(Q,p->rchild); //右子女入队

else if (p->rchild) return 0; else tag=1;

} //while

return 1; } //JudgeComplete

5、连通图的生成树包括图中的全部n个顶点和足以使图连通的n-1条边,最小生成树是边上权值之和最小的生成树。故可按权值从大到小对边进行排序,然后从大到小将边删除。每删除一条当前权值最大的边后,就去测试图是否仍连通,若不再连通,则将该边恢复。若仍连通,继续向下删;直到剩n-1条边为止。

void SpnTree (AdjList g)

//用“破圈法”求解带权连通无向图的一棵最小代价生成树。

{typedef struct {int i,j,w}node; //设顶点信息就是顶点编号,权是整型数

node edge[];

scanf( "%d%d",&e,&n) ; //输入边数和顶点数。

for (i=1;i<=e;i++) //输入e条边:顶点,权值。

scanf("%d%d%d" ,&edge[i].i ,&edge[i].j ,&edge[i].w);

for (i=2;i<=e;i++) //按边上的权值大小,对边进行逆序排序。

{edge[0]=edge[i]; j=i-1;

while (edge[j].w

edge[j+1]=edge[0]; }//for

k=1; eg=e;

while (eg>=n) //破圈,直到边数e=n-1.

{if (connect(k)) //删除第k条边若仍连通。

{edge[k].w=0; eg--; }//测试下一条边edge[k],权值置0表示该边被删除k++; //下条边

}//while

}//算法结束。

connect()是测试图是否连通的函数,可用图的遍历实现,

6、二路插入排序是将待排关键字序列r[1..n]中关键字分二路分别按序插入到辅助向量d[1..n]前半部和后半部(注:向量d可视为循环表),其原则为,先将r[l]赋给d[1],再从r[2] 记录开始分二路插入。编写实现二路插入排序算法。

7、设t是给定的一棵二叉树,下面的递归程序count(t)用于求得:二叉树t中具有非空的左,右两个儿子的结点个数N2;只有非空左儿子的个数NL;只有非空右儿子的结点个数NR和叶子结点个数N0。N2、NL、NR、N0都是全局量,且在调用count(t)之前都置为0.

typedef struct node

{int data; struct node *lchild,*rchild;}node;

int N2,NL,NR,N0;

void count(node *t)

{if (t->lchild!=NULL) if (1)___ N2++; else NL++;

else if (2)___ NR++; else (3)__ ;

if(t->lchild!=NULL)(4)____; if (t->rchild!=NULL) (5)____;

}

26.树的先序非递归算法。

void example(b)

btree *b;

{ btree *stack[20], *p;

int top;

if (b!=null)

{ top=1; stack[top]=b;

while (top>0)

{ p=stack[top]; top--;

printf(“%d”,p->data);

if (p->rchild!=null)

{(1)___; (2)___;

}

if (p->lchild!=null)

(3)___; (4)__;

}}}}

相关文档
最新文档