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:
时间复杂度很重要,最好让其较小。
一般如果说元素的范围了,就可能是再设置一个数组。