2009年计算机考研题解

2009年计算机考研题解

之数据结构综合题部分

作者:朱云翔

综合第一题:

【题目】
   41.(10分)
    带权图(权值非负,表示边连接的两顶点间的距离)的最短路径问题是找出冲初始顶点到目标顶点之间的一条最短路径,假设从 初始顶点到目标顶点之间存在路径,现有一种解决该问题的方法:
    (1)该最短路径初始时仅包含初始顶点,令当前顶点u为初始顶点;
    (2)选择离u最近且尚未在最短路径中的一个顶点v,加入到最短路径中,修改当前顶点u=v;
    (3)重复步骤(2),直到u是目标顶点时为止。
    请问上述方法能否求得最短路径?若该方法可行,请证明之,否则请举例说明。
【答案】:
   很显然不能。这就是传说中的贪心法,用贪心法是没有好结果的!不过本方法与迪杰斯特拉(Dijkstra)算法有点相似,不仔细的会背错。呵呵。
   举例说明:如下图,括号中的是权(路径长度),顶顶是点,从0到3,如果按照贪心法,将走0-2-3,而实际最短为0-1-3。呵呵。
 
0-----(1)――――――2
|                           |
|                           |
(2)                       (10)
|                           |
|                           |    
1―――――-(2)―――――-―3

综合第二题:

【题目】
   42.(15分)
    已知一个带有表头结点的单链表,结点结构为:
    假设该链表只给出了头指针list,在不改变链表的前提下,请设计一个尽可能高效的算法,查找链表中倒数第K个位置上的结点 (K为正整数),若查找成功,算法输出该结点的data域的值,并返回1;否则只返回0。要求:
    (1)描述算法的基本设计思想;
    (2)描述算法的详细实现步骤(使用C或 C++ 或 Java 语言实现),关键之处请给出简要注释。
【答案】:
    增加2个指针变量和一个整型变量,从链表头向后遍历,其中指针p指向当前遍历的结点,指针p1指向p1所指向结点的前k个结点,如果p之前没有k个结点,那么p1指向表头结点。用整型变量i表示当前遍历了多少个结点,当i>k时,p1随着每次的遍历,也向请移动一个结点。则遍历完成时,p1或者指向表头结点,或者指向链表中倒数第k个位置上的结点。


【算法1】:空间3,时间n
p=list->link;
p1=list;
i=1;
while(p)
{
    p=p->link;
    i++;
    if (i>k) p1=p1->next;
}
if (p1==list) return 0;
else
{
    printf("%d\n", p1->data);
    return 1;
}

 
【算法2】:空间3,时间n

p=list->link;
p1=list;
i=1;
while(p&&i<k)
{
    p=p->link;
    i++;
}
if (!p) return 0;
while(p)
{
    p=p->link;
    p1=p1->next;
}
printf("%d\n", p1->data);
return 1;

【算法3】:
首先遍历整个链表,获取链表的长度n。
再重新遍历到链表的第n-k+1个结点,即为所求
空间:2,时间2n
p=list->link;
i=0;
while(p)
{
    p=p->link;
    i++;
}
if (i<k) return 0;
p=list->link
while(i>k)
{
    p=p->link;
    i--;
}
printf("%d\n", p1->data);
return 1;

【比较】:
空间复杂度:算法3最好。
时间复杂度:算法2最好。
程序清晰度:算法1最好。
为什么算法2的时间复杂度要要高于算法1的?
因为算法1和算法2都遍历了n次,但是算法1的循环体中有3行代码,而算法2中只有2行代码。但是算法2的程序比算法1复杂,故算法2是空间换取时间。
【建议】
在考研时尽量选择算法1,因为一方面它的效率高,另一方面它比较清晰、简单。 尽量不要选择算法3,因为他的效率最低,为O(2n)。至于算法2,可在实际生产中有选择的使用,选择条件为:不会写算法1的同学或者其它相关条件。
 
考研书籍介绍
 

你可能感兴趣的:(题解,职场,计算机,考研,休闲)