考研数据结构(每日一题)
题目:用单链表保存m个整数,结点的结构为[data][link],且|data|<=n(n为正整数),要求设计一个时间复杂度尽可能高效的算法,对于链表中data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表head如下:
则删除结点后的head为:
算法思想:
核心思想是用空间换时间。使用辅助数组记录链表中已出现的数值,只需对链表进行一趟扫描。
|data|<=n,所以辅助数组q的大小为n+1,各元素的初始值为0,一次扫描链表中的各个结点,同时检查q[|data|]的值,若为0则保留该结点,并令q[|data|]=1,否则将该结点从链表中删除。
完整代码:
typedef struct node{
int data;
struct node *link;
}NODE;
Typedef NODE *PNODE;
void function(PNODE h,int n){
PNODE p = h, r;
int *q,m;
q = (int *)malloc(sizeof(int)*(n+1)); //申请n+1位置的辅助空间
for(int i = 0;i < n + 1;i ++){ //数组元素初始值为0
*(q + i) = 0;
}
while(p -> link != NULL){
m = p -> link -> data > 0 ? p -> link -> data : -p -> link -> data;
if(q[m] == 0){ //判断该结点的data是否已出现过
q[m] = 1; //首次出现
p = p -> link; //保留
}else{ //若重复出现
r = p -> link; //删除
p -> link = r -> link;
free(r);
}
}
free(q);
}