考研数据结构(每日一题)day24

128 阅读1分钟

考研数据结构(每日一题)

题目:用单链表保存m个整数,结点的结构为[data][link],且|data|<=n(n为正整数),要求设计一个时间复杂度尽可能高效的算法,对于链表中data的绝对值相等的结点,仅保留第一次出现的结点而删除其余绝对值相等的结点。例如,若给定的单链表head如下:

Snipaste_2022-03-18_11-23-28.png

则删除结点后的head为:

Snipaste_2022-03-18_11-23-35.png

算法思想:

核心思想是用空间换时间。使用辅助数组记录链表中已出现的数值,只需对链表进行一趟扫描。

|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);
}