设A=( a1,a2,a3,…an),B=( b1,b2,b3…bn )是两个递增有序的线性表(其中n、m均大于1),且所有数据元素均不同。假设A、B均采用带头结点的单链表存放,设计一个尽可能高效的算法判断B是否为A的一个连续子序列,并分析你设计的算法的时间复杂度和空间复杂度。
#include <stdio.h>
#include <malloc.h>
typedef struct LinkList
{
int data;
struct LinkList*next;
}node;
node* create() //创建链表,带头结点
{
node* head;
head = (node*)malloc(sizeof(node));
head->next = NULL;
return head;
}
node* tail_insert(node* head, int value) //尾插法
{
node* p, * t;
t = head;
p = (node*)malloc(sizeof(node));
p->data = value;
while (t->next != NULL) //当链表不为空时t向后移动
t = t->next;
t->next = p;
p->next = NULL;
return head;
}
node* display(node* head) //打印链表数据
{
node* p;
p = head->next;
if (p == NULL)
{
printf("linklist is empty...\n");
return;
}
while (p != NULL)
{
printf("%5d", p->data);
p = p->next;
}
printf("\n");
return head;
}
int SubSeq(node *A, node*B){
node*p = A->next, *q = B->next;
while (p != NULL && q != NULL) //找两个单链表中第一个值相同的节点
{
if (p->data < q->data)
p = p->next;
else if (p->data > q->data)
q = q->next;
else
break;
}
while (p != NULL && q != NULL && p->data == q->data)
{ //当两者值相等时同步后移
p = p->next;
q = q->next;
}
if (q == NULL) //当B中节点比较完毕返回1
{
printf("是子序列\n");
return 1;
}
else //否则返回0
{
printf("不是子序列\n");
return 0;
}
};
void main()
{
node* head;
head = create();
node* head2;
head2 = create();
printf("head:\n");
for (int i = 1;i < 10;i++) {
tail_insert(head, i);
}
display(head);
printf("head2:\n");
for (int i = 9;i < 20;i++) {
tail_insert(head2, i);
}
display(head2);
SubSeq(head, head2);
};
分别循环有序单链表A、B,先找到第一个两者值相等的节点,然后在两者值相等时同步后移,判断B是否扫描完毕。
时间复杂度为O(m+n),空间复杂度为O(1)。