2024王道408数据结构 P39 T24
思考过程
- 首先我们还是先看懂题目的意思,题目说如果有绝对值相同的值,要我们删除只留下第一个值,然后题目说需要高效的算法,那我们就直接牺牲空间来换取时间。这道题我们可以用一个辅助数组*q,题目也说了data的绝对值≤n,我们就给数组q开辟n+1个int空间。
- 举个例子单链表长这个样子,
表中最大值是4,我们就给q开4+1个空间,q=(int*)malloc(sizeof((int)*(n+1));
同时把其中的值初始化为0,for(int i = 0;i<n;i++) *(q+i) = 0
。 - 用桶排序的原理,我们只需要用一个指针p遍历单链表L,并且还需要一个int类型的s来帮我们存表中的绝对值。
int s = abs(p->next->data);
- 以上面这个例子开始让p指针遍历链表L,当指针遍历到第一个元素4的时候,我们判断数组q中下标为4的位置中的值,如果为0的话就代表之前这个值没有出现过,这个时候就让p往下移,同时把数组下标为4的位置赋值为1。
if (*(q+s)=0) *(q+s)=1;p=p->next;
- 当p遍历到第二个元素-2时,同样我们判断数组q中下标为2的值是否为0,如果为0的话就代表之前这个数字没有出现过,我们就让p往下移,同时把q中下标为2的位置的值赋值为1。
- 当p遍历到第三个元素2时,我们判断数组q中下标为2的值,发现此时下标为2的值已经为1,代表数字2之前就已经出现过,
这时候我们需要一个指针f用来删除第三个元素2,f = p->next;p->next = f->next;free(f);
这样就把第三个元素2删除了,
接下来继续指针p继续往下遍历就行了。
原理就是这么个原理,理解了桶排序之后就好做很多了,就是用空间换时间。记得最后再把我们申请的q空间给free掉就大功告成了。
完整代码附上:
//
// Created by 黎圣 on 2023/7/28.
//
#include "iostream"
typedef struct node
{
int data;
struct node *next;
}*linklist;
//我举的例子
int a[] = {4,-2,2,-3,-2};
int n = 5;
//创建单链表L
void CreateList(linklist &L)
{
L = (linklist)malloc(sizeof(struct node));
struct node *s, *r = L;
for (int i = 0; i < n; i++)
{
s = (linklist)malloc(sizeof(struct node));
s->data = a[i];
r->next = s;
r = r->next;
}
r->next = NULL;
}
//打印出来方便观察
void display(linklist L)
{
struct node *s = L->next;
while (s)
{
printf("%d ", s->data);
s = s->next;
}
printf("\n");
}
//题目主代码
void deletesame(linklist L, int n)
{
struct node *p = L, *f;
int *q;
int s = 0;
q = (int *)malloc(sizeof(int)*(n+1));//给数组q开辟n+1个空间
for (int i = 0; i < n; i++)
*(q + i) = 0;//初始化数组q,里面全放0
while (p->next != NULL)
{
s = abs(p->next->data);//s里面放data值的绝对值
if (*(q + s) == 0)//没出现过
{
*(q + s) = 1;
p = p->next;
}
else//该元素之前出现过
{
//删除结点
f = p->next;
p->next = f->next;
free(f);
}
}
free(q);
}
int main()
{
linklist L;
CreateList(L);
display(L);
deletesame(L, 5);
display(L);
return 0;
}
最后感谢b站up主@吸血小金鱼,好累…🥱