【数据结构】课后作业——仅保留链表中绝对值相同的第一个数

P38.23

有一个整型链表,共有m个元素,每个元素都不大于n。保留遇到的所有绝对值相同中的元素中的第一个,其余删除。

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

取三个指针。第一个一个一个往后,第二个在第一个为某个值时一个一个往后,第三个作为第二个的前驱。

第一个为某个值时,第二个将其后所有值与其比较,删除相同的值。第一个值不断往后直到最后一个。

(2)代码如下

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef int 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("%d ", s->data);
		s = s->next;
	}
}
LinkList CreatListend(LinkList &L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%d", &x);
	while (x != 9999)
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return L;
}
void main()
{
	int count;
	LinkList L;
	CreatListend(L);
	printList(L);
	LNode *first, *preNode, *nowNode;
	first = L->next;
	preNode = L->next;
	nowNode = L->next->next;
	while (first != NULL)
	{
		while (nowNode != NULL)
		{
			if (abs(first->data) == abs(nowNode->data))
			{
				preNode->next = nowNode->next;
				free(nowNode);
				nowNode = preNode->next;
			}
			else if (nowNode == NULL)
				break;
			else
			{
				nowNode = nowNode->next;
				preNode = preNode->next;
			}
		}
		first = first->next;
		preNode = first;
		if (first == NULL)
			break;
		nowNode = first->next;
	}
	printList(L);
}

(3)复杂度

时间复杂度O(m^2)

空间复杂度O(n)

较好的算法

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

以时间换空间。设置一个元素个数为n的数组。初值为0。遍历链表,第一次遇到的链表元素,将其对应的数组下标的元素置一。之后每遍历一个链表元素,如果对应的数组元素为0,则置一,如果不为零,删去该链表元素。

(2)代码

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
typedef int 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("%d ", s->data);
		s = s->next;
	}
}
LinkList CreatListend(LinkList &L)
{
	int x;
	L = (LinkList)malloc(sizeof(LNode));
	LNode *s, *r = L;
	scanf("%d", &x);
	while (x != 9999)
	{
		s = (LNode *)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = s;
		scanf("%d", &x);
	}
	r->next = NULL;
	return L;
}
unsigned int* array(unsigned int i)//C中不能新建数组元素为变量的数组,该函数用于实现这一功能
{
	unsigned int *arr;//指针用于指向数组的首地址
	unsigned int j = 0;
	arr = (unsigned int *)malloc(sizeof(int)*i);//分配数组地址空间
	for (j = i; j>0; j--)
		arr[j - 1] = 0;
	return arr;
}
void main()
{
	int count;
	LinkList L;
	CreatListend(L);
	printList(L);
	int n;
	scanf("%d", &n);
	unsigned int* A = array(n);
	LNode *nowNode, *preNode;
	nowNode = L->next;
	preNode = L;
	while (nowNode != NULL)
	{
		if (A[abs(nowNode->data)] == 0)
		{
			A[abs(nowNode->data)]++;
			nowNode = nowNode->next;
			preNode = preNode->next;
		}
		else
		{
			preNode->next = nowNode->next;
			free(nowNode);
			nowNode = preNode->next;
		}
	}
	printList(L);
}

(3)复杂度

时间复杂度O(m)

空间复杂度O(n)

PS:

时间复杂度很重要,最好让其较小。

一般如果说元素的范围了,就可能是再设置一个数组。

猜你喜欢

转载自blog.csdn.net/erwugumo/article/details/81509277