用单链表保存m个整数,结点的结构为((data,link),且ldatalsn(n为正整数)。现要求设 计一个时间复杂度尽可能高效的算法,对干链表中data绝对值相等的结点,仅保留第一次 出现的结点,而删除共余绝对值相等的结点。要求 (1)描述算法思想并将算法实现 (2)编写C程序,在main西数中创建图示例子中的包含head结点以及5个数据结点的链 表;数据结点数据域的值与例子中的一致,将原始表数据域依次输出;对干链表中data绝 对值相等的结点,仅保留第一次出现的结点,将删除后的链表数据域依次输出。 (3)c程序中,关键步聚要加注释说明
时间: 2024-02-17 11:02:23 浏览: 16
算法思想:
1. 对于每个节点,将该节点的data的绝对值作为下标,插入到一个长度为m的数组中。
2. 如果该下标对应的数组元素为空,则将该节点插入到该位置。
3. 如果该下标对应的数组元素不为空,则代表该位置已经存在节点的data的绝对值相等,需要将该节点从链表中删除,并将该位置的节点更新为当前节点。
4. 遍历完整个链表后,将新生成的链表返回。
C程序实现如下:
```c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#define MAX_SIZE 100
// 定义节点结构体
typedef struct Node{
int data;
struct Node *link;
}Node;
// 建立链表
Node *createList(int *arr, int n) {
Node *head = (Node *)malloc(sizeof(Node));
Node *p = head;
for (int i = 0; i < n; i++) {
Node *node = (Node *)malloc(sizeof(Node));
node->data = arr[i];
node->link = NULL;
p->link = node;
p = node;
}
return head;
}
// 删除链表中所有data相等的节点,仅保留第一个
Node *deleteDuplicate(Node *head) {
Node *p = head->link;
Node *q = head->link;
Node *arr[MAX_SIZE] = {0};
while (p) {
int index = abs(p->data) % MAX_SIZE;
if (arr[index] == NULL) {
arr[index] = p;
q = p;
} else {
q->link = p->link;
free(p);
p = q->link;
continue;
}
p = p->link;
}
return head;
}
// 打印链表
void printList(Node *head) {
Node *p = head->link;
while (p) {
printf("%d ", p->data);
p = p->link;
}
printf("\n");
}
int main() {
// 测试数据
int arr[5] = {1, 2, -3, 2, -1};
Node *head = createList(arr, 5);
printf("原始链表:\n");
printList(head);
head = deleteDuplicate(head);
printf("删除重复节点后的链表:\n");
printList(head);
return 0;
}
```
关键步骤注释说明如下:
1. 定义了节点的结构体,包括数据data和指向下一个节点的指针link:
```c
typedef struct Node{
int data;
struct Node *link;
}Node;
```
2. 建立链表时,每次创建一个新节点,并将该节点插入到链表的末尾:
```c
Node *createList(int *arr, int n) {
Node *head = (Node *)malloc(sizeof(Node));
Node *p = head;
for (int i = 0; i < n; i++) {
Node *node = (Node *)malloc(sizeof(Node));
node->data = arr[i];
node->link = NULL;
p->link = node;
p = node;
}
return head;
}
```
3. 删除链表中所有data相等的节点,仅保留第一个。使用一个数组arr来保存data的绝对值作为下标对应的节点,如果该下标对应的数组元素为空,则将该节点插入到该位置;如果该下标对应的数组元素不为空,则代表该位置已经存在节点的data的绝对值相等,需要将该节点从链表中删除,并将该位置的节点更新为当前节点:
```c
Node *deleteDuplicate(Node *head) {
Node *p = head->link;
Node *q = head->link;
Node *arr[MAX_SIZE] = {0};
while (p) {
int index = abs(p->data) % MAX_SIZE;
if (arr[index] == NULL) {
arr[index] = p;
q = p;
} else {
q->link = p->link;
free(p);
p = q->link;
continue;
}
p = p->link;
}
return head;
}
```
4. 打印链表时,遍历链表中的每个节点,并输出该节点的数据域data:
```c
void printList(Node *head) {
Node *p = head->link;
while (p) {
printf("%d ", p->data);
p = p->link;
}
printf("\n");
}
```