天天看点

【数据结构】课后作业——返回后缀中的第一个元素

P38.22

有A、B两个字符串,以链表形式存放。他们有相同的后缀,请给出后缀的第一个字母。

(1)算法的基本设计思想

分别遍历一遍链表并将其倒置为新的链表。则两个新的链表的第一个不同的元素之前的元素就是所需的元素。

倒置采用的是头插法来生成两个新的链表。

(2)代码如下

#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode, *LinkList;
void printList(LinkList &L)
{
	printf("\n");
	LNode *s=L->next;
	while (s != NULL)
	{
		printf("%c", s->data);
		s = s->next;
	}
}
LinkList CreatListend(LinkList &L,LinkList &end)
{
	char x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%c", &x);
	while (x != '@')
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%c", &x);
	}
	end = r;
	r->next = NULL;
	return L;
}
void main()
{
	int count;
	LinkList L1, L2, L3;
	LinkList _L1, _L2;
	LinkList end1=NULL, end2=NULL,end3=NULL;
	CreatListend(L1,end1);
	CreatListend(L2,end2);
	CreatListend(L3,end3);
	end1->next = L3->next->next;
	end2->next = L3->next->next;
	printList(L1);
	printList(L2);
	_L1= (LinkList)malloc(sizeof(LNode));
	_L2= (LinkList)malloc(sizeof(LNode));
	_L1->next = NULL;
	_L2->next = NULL;
	LNode *s1,*s2;
	while (L1 != NULL)
	{
		s1 = (LNode*)malloc(sizeof(LNode));
		s1->data = L1->data;
		s1->next = _L1->next;
		_L1->next = s1;
		L1 = L1->next;
	}
	while (L2 != NULL)
	{
		s2 = (LNode*)malloc(sizeof(LNode));
		s2->data = L2->data;
		s2->next = _L2->next;
		_L2->next = s2;
		L2 = L2->next;
	}
	if (_L1->data != _L2->data)
		printf("无共同后缀");
	else
		while (_L1->next->data == _L2->next->data)
		{
			_L1 = _L1->next;
			_L2 = _L2->next;
		}
	printf("后缀起始字母为%c", _L1->data);
}
           

(3)复杂度

时间复杂度O(n)

空间复杂度O(n)

较好的算法

(1)算法的基本设计思想

曾经考虑过这样一个算法,但是由于对指针指向不是很熟练而放弃。就是设置两个指针,分别指向两链表。向后移动,直到两指针的地址相同时就是后缀的第一个字母。当然该算法需要知道两个链表各自的长度,因此时间上也没有好多少。

(2)代码

#include <stdio.h>
#include <stdlib.h>
typedef char ElemType;
typedef struct LNode {
	ElemType data;
	struct LNode *next;
}LNode, *LinkList;//LNode是结构变量,LinkList是结构指针
int countList(LinkList &L)
{
	int count = 0;
	LNode *s = L->next;
	while (s != NULL)
	{
		s = s->next;
		count++;
	}
	return count;
}
void printList(LinkList &L)
{
	printf("\n");
	LNode *s=L->next;
	while (s != NULL)
	{
		printf("%c", s->data);
		s = s->next;
	}
}
LinkList CreatListend(LinkList &L,LNode* &end)//返回的尾指针的类型应该是结构指针LinkList,也可以是LNode*,不能是结构变量LNode。当然要改变它的值,那么传入的就得是地址了
{
	char x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%c", &x);
	while (x != '\n')
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%c", &x);
	}
	end = r;
	r->next = NULL;
	return L;
}
void main()
{
	int count;
	LinkList L1, L2, L3;
	LinkList end1=NULL, end2=NULL,end3=NULL;
	CreatListend(L1,end1);
	CreatListend(L2,end2);
	CreatListend(L3,end3);
	end1->next = L3->next;
	end2->next = L3->next;
	printList(L1);
	printList(L2);
	int count1 = countList(L1);
	int count2 = countList(L2);
	LNode *p, *q;
	for (p = L1; count1 > count2; count1--)
		p = p->next;
	for (q = L2; count1 < count2; count2--)
		q = q->next;
	while (p->next != NULL&&p->next != q->next)
	{
		p = p->next;
		q = q->next;
	}
	if (p->next == NULL)
		printf("无共同后缀");
	else
		printf("后缀起始字母为%c", p->next->data);
}
           

(3)复杂度

时间复杂度O(n)

空间复杂度O(n)

PS:

人家的算法肯定符合要求,人家返回的是地址,我返回的是值。而且当我的在后缀之前有一个字母是相同的时候,就出现了错误。总而言之还是我蠢。

继续阅读