王道数据结构课后代码题p41 第23题链表结点结构为data和next请设计一个时间上尽可能高效的算法,找出由 str1和 str2 所指向两个链表共同后缀的起始位置(c语言代码实现)

   23.[2012 统考真题]假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时可共享相同的后缀存储空间,例如,“loading”和“being”的存储映像设 strl和str2分别指向两个单词所在单链表的头结点,链表结点结构为datanext请设计一个时间上尽可能高效的算法,找出由 str1和 str2 所指向两个链表共同后缀的起始位置

目录

本题代码如下

可以这样计算链表长度

完整测试代码


本题代码如下

//我这个在外面已经计算好了两个字符串的长度,所以直接传值进去了

linklist find(linklist *L1,linklist *L2,int sza,int szb)
{
	lnode* p, * q;
		for (p = *L1; sza > szb; sza--)//若sza>szb,使p指向链表中的第m-n+1个结点
			p = p->next;
		for (q = *L2; szb > sza; szb--)//若szb>sza,使q指向链表中的第n-m+1个结点
			q = q->next;
	while (p->next!=NULL&&p->next->data!=q->next->data)//将p与q同步后移
	{
		p = p->next;
		q = q->next;
	}
	return p->next;//返回公共后缀的起始地址
}

可以这样计算链表长度

int listlen(linklist *L)
{
    int len=0;
    while((*L)->next!=NULL)
    {
        len++;
        *L=(*L)->next;
    }
    return len;
}

完整测试代码

#include
#include
typedef struct lnode
{
	char data;
	struct lnode* next;
}lnode, * linklist;
char a[7] = { "loading" };
char b[5] = { "being" };
int len(char arr[])
{
	int i = 0;
	int count = 0;
	for (i = 0; arr[i] != '\0'; i++)
		count++;
	return count;
}
void buildlinklist(linklist* L,char arr[],int n)
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = arr[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
linklist find(linklist *L1,linklist *L2,int sza,int szb)//我这个在外面已经计算好了两个字符串的长度,所以直接传值进去了
{
	lnode* p, * q;
		for (p = *L1; sza > szb; sza--)
			p = p->next;
		for (q = *L2; szb > sza; szb--)
			q = q->next;
	while (p->next!=NULL&&p->next->data!=q->next->data)
	{
		p = p->next;
		q = q->next;
	}
	return p->next;
}
void print(linklist *L)
{
	lnode* k = (*L)->next;
	while (k)
	{
		printf("%c ", k->data);
		k = k->next;
	}
}
int main()
{
	int sza = len(a);
	int szb = len(b);
	linklist L1,L2;
	buildlinklist(&L1,a,sza);
	printf("原始的L1单链表为:");
	print(&L1);
	buildlinklist(&L2, b, szb);
	printf("\n原始的L2单链表为:");
	print(&L2);
	linklist C=find(&L1, &L2, sza, szb);
	printf("\n公共首结点为:%c", C->data);
	return 0;
}

3119830b5d7241b0b5a6e8aea310dab6.png

也可以这样写(差不多的思路)其实也还可以暴力求解(这里就没写啦)

linklist find(linklist* L1, linklist* L2, int sza, int szb)
{
	lnode* p=(*L1)->next, * q=(*L2)->next;
	if (sza > szb)//如果sza大于szb
	{
		int dist = sza - szb;
		for (int i = 0; i < dist; i++)//让p移动到与q到表尾长度相同的位置
			p = p->next;
	}
	if (sza < szb)//如果sza小于szb
	{
		int dist = szb - sza;
		for (int i = 0; i < dist; i++)//让q移动到与p到表尾长度相同的位置
			q = q->next;
	}
	while (p && q)//一起向后遍历
	{
		if (p->data == q->data)//遇到了就返回结点的值
			return p;
		else
		{
			p = p->next;
			q = q->next;
		}
	}
	return 0;
}

完整测试代码为

#include
#include
typedef struct lnode
{
	char data;
	struct lnode* next;
}lnode, * linklist;
char a[7] = { "loading" };
char b[5] = { "being" };
int len(char arr[])
{
	int i = 0;
	int count = 0;
	for (i = 0; arr[i] != '\0'; i++)
		count++;
	return count;
}
void buildlinklist(linklist* L, char arr[], int n)
{
	*L = (lnode*)malloc(sizeof(lnode));
	(*L)->next = NULL;
	lnode* s = *L, * r = *L;
	int i = 0;
	for (i = 0; i < n; i++)
	{
		s = (lnode*)malloc(sizeof(lnode));
		s->data = arr[i];
		s->next = r->next;
		r->next = s;
		r = s;
	}
	r->next = NULL;
}
linklist find(linklist* L1, linklist* L2, int sza, int szb)//我这个在外面已经计算好了两个字符串的长度,所以直接传值进去了
{
	lnode* p=(*L1)->next, * q=(*L2)->next;
	if (sza > szb)//如果sza大于szb
	{
		int dist = sza - szb;
		for (int i = 0; i < dist; i++)//让p移动到与q到表尾长度相同的位置
			p = p->next;
	}
	if (sza < szb)//如果sza小于szb
	{
		int dist = szb - sza;
		for (int i = 0; i < dist; i++)//让q移动到与p到表尾长度相同的位置
			q = q->next;
	}
	while (p && q)//一起向后遍历
	{
		if (p->data == q->data)//遇到了就返回结点的值
			return p;
		else
		{
			p = p->next;
			q = q->next;
		}
	}
	return 0;
}
void print(linklist* L)
{
	lnode* k = (*L)->next;
	while (k)
	{
		printf("%c ", k->data);
		k = k->next;
	}
}
int main()
{
	int sza = len(a);
	int szb = len(b);
	linklist L1, L2;
	buildlinklist(&L1, a, sza);
	printf("原始的L1单链表为:");
	print(&L1);
	buildlinklist(&L2, b, szb);
	printf("\n原始的L2单链表为:");
	print(&L2);
	linklist C = find(&L1, &L2, sza, szb);
	printf("\n公共首结点为:%c", C->data);
	return 0;
}

你可能感兴趣的:(王道课后习题单链表,数据结构,算法,链表,c语言)