前言:目前大二学习数据结构,发现只是看或者填空代码是远远不够的,必须亲自用IDE打一遍印象才深,从这篇博客开始,对历年初试、复试的经典习题进行讲解,希望能够帮助像我一样在考研路上奋斗的学生,如有错误欢迎指出。本片文章以及以后的文章参考“算法与数据结构考研试题精析”,如有错误欢迎指出。
1 清华大学1994 15分
两个有序 的单链表ha, hb, 请判断链表a是否包含在链表b内。
首先创建我们的情景
typedef struct _LinkList
{
int data;
struct _LinkList *next;
}LinkList;
/*构建两个有序链表*/
void creat1(LinkList *head) //1 2 3 4 5
{
int i = 0;
LinkList *pcur = head;
for (i = 0; i<5;i++)
{
LinkList *pm = (LinkList*)malloc(sizeof(LinkList));
pm->data = i+1;
pm->next = NULL;
pcur->next = pm;
pcur = pm;
}
}
void creat2(LinkList *head) // 1 3 5
{
int i = 0;
LinkList *pcur = head;
for (i = 0; i<3;i++)//1 3 5
{
LinkList *pm = (LinkList*)malloc(sizeof(LinkList));
pm->data = 2*i+1;
pm->next = NULL;
pcur->next = pm;
pcur = pm;
}
}
再说思路:
首先由头结点指向链表的开始节点
LinkList *pa = ha->next;
LinkList *pb = hb->next;
只有当pb的data比pa小才干接下来的工作,如果pb最小的都要比pa大那么肯定就不是包含关系了
while ( pb && pa->data >= pb->data )
{
// 关键代码
}
return 0;
现在来考虑关键代码
如果pa与pb相等,那么我们就要继续比较,也就是
if (pa->data == pb->data)
{
return inclusion(pa, pb);//注意
}
如果不相等,那么我们的b后移一次,看看是否相等
else
{
pb = pb->next;
}
这是用了递归的方法,我们还要再考虑递归结束的条件,如果pa一直走,就算是走到了最后也没有出现return 0的状况,则说明a是包含在b中的。
好了,我们完善一下代码
int inclusion(LinkList *ha, LinkList *hb)
{
LinkList *pa = ha->next;
LinkList *pb = hb->next;
if (pa == NULL)
{
return 1;
}
while ( pb && pa->data >= pb->data )
{
if (pa->data == pb->data)
{
return inclusion(pa, pb);
}
else
{
pb = pb->next;
}
}
return 0;
}
走一次测试案例
void main()
{
LinkList *head1 = (LinkList *)malloc(sizeof(LinkList));
LinkList *head2 = (LinkList *)malloc(sizeof(LinkList));
creat1(head1);
creat2(head2);
printf("%d",inclusion(head2, head1));
system("pause");
}
最后唠叨一下递归的流程