用类c描述链表节点的定义和初始化、查找、销毁等基本操作,再将(3,6,8,9)和(2,5,8,10,12,16)两个非递减的有序链表合并为一个非递增的有序链表,仍然用原来的存储空间,并且要有每步操作的注释。
时间: 2023-08-31 13:41:06 浏览: 91
一算法可实现两个非递减的线性表的合并,采用链式存储结构,能够输出合并前和合并后链表的内容
### 回答1:
以下是用 C 语言描述链表节点的定义和基本操作的代码:
```c
#include <stdio.h>
#include <stdlib.h>
// 定义链表节点
typedef struct ListNode {
int val;
struct ListNode *next;
} ListNode;
// 初始化链表
void initList(ListNode **head) {
*head = NULL;
}
// 查找节点
ListNode* searchList(ListNode *head, int val) {
ListNode *p = head;
while (p != NULL && p->val != val) {
p = p->next;
}
return p;
}
// 插入节点
void insertList(ListNode **head, int val) {
ListNode *p = (ListNode*)malloc(sizeof(ListNode));
p->val = val;
p->next = NULL;
if (*head == NULL) {
*head = p;
} else {
ListNode *q = *head;
while (q->next != NULL) {
q = q->next;
}
q->next = p;
}
}
// 删除节点
void deleteList(ListNode **head, int val) {
if (*head == NULL) {
return;
}
if ((*head)->val == val) {
*head = (*head)->next;
return;
}
ListNode *p = *head;
while (p->next != NULL && p->next->val != val) {
p = p->next;
}
if (p->next != NULL) {
p->next = p->next->next;
}
}
// 销毁链表
void destroyList(ListNode **head) {
ListNode *p = *head;
while (p != NULL) {
ListNode *q = p->next;
free(p);
p = q;
}
*head = NULL;
}
```
接下来是将两个非递减的有序链表合并为一个非递增的有序链表的代码,假设两个链表的头节点分别为 `l1` 和 `l2`:
```c
// 合并链表
ListNode* mergeList(ListNode *l1, ListNode *l2) {
if (l1 == NULL) {
return l2;
}
if (l2 == NULL) {
return l1;
}
ListNode *head = NULL;
ListNode *tail = NULL;
while (l1 != NULL && l2 != NULL) {
if (l1->val > l2->val) {
ListNode *p = l1;
l1 = l2;
l2 = p;
}
if (head == NULL) {
head = l1;
} else {
tail->next = l1;
}
tail = l1;
l1 = l1->next;
}
if (l1 != NULL) {
tail->next = l1;
}
if (l2 != NULL) {
tail->next = l2;
}
return head;
}
```
注释解释:
1. `mergeList` 函数的参数是两个链表的头节点 `l1` 和 `l2`,返回值是合并后的链表的头节点。
2. 如果 `l1` 或 `l2` 中有一个为空,直接返回另一个链表。
3. 定义两个指针 `head` 和 `tail`,分别表示合并后链表的头和尾,初始化都为 `NULL`。
4. 比较 `l1` 和 `l2` 当前节点的值,将较小的节点加入合并后的链表。
5. 如果 `head` 为空,说明当前节点是第一个加入链表的节点,需要将 `head` 指向它。
6. 否则,将 `tail` 的 `next` 指针指向当前节点。
7. 将 `tail` 指向当前节点,表示当前节点是链表的最后一个节点。
8. 将 `l1` 或 `l2` 中的一个节点指针向后移动。
9. 如果 `l1` 或 `l2` 中还有剩余的节点,将它们全部加入合并后的链表。
10. 返回合并后的链表的头节点 `head`。
最后,我们可以调用上述函数来将 `(3,6,8,9)` 和 `(2,5,8,10,12,16)` 两个有序链表合并,结果为 `(16,12,10,9,8,8,6,5,3,2)`:
```c
int main() {
// 初始化链表
ListNode *l1, *l2;
initList(&l1);
initList(&l2);
// 插入节点
insertList(&l1, 3);
insertList(&l1, 6);
insertList(&l1, 8);
insertList(&l1, 9);
insertList(&l2, 2);
insertList(&l2, 5);
insertList(&l2, 8);
insertList(&l2, 10);
insertList(&l2, 12);
insertList(&l2, 16);
// 合并链表
ListNode *head = mergeList(l1, l2);
// 打印合并后的链表
ListNode *p = head;
while (p != NULL) {
printf("%d ", p->val);
p = p->next;
}
printf("\n");
// 销毁链表
destroyList(&head);
return 0;
}
```
### 回答2:
链表节点的定义和初始化:
```c
typedef struct ListNode {
int val; //节点值
struct ListNode *next; //指向下一个节点的指针
} ListNode;
ListNode* createNode(int value) {
ListNode* newNode = (ListNode*)malloc(sizeof(ListNode)); //为新节点分配内存空间
newNode->val = value; //设置节点值
newNode->next = NULL; //将下一个节点指针初始化为空
return newNode;
}
```
链表的查找操作:
```c
ListNode* search(ListNode* head, int value) {
ListNode* current = head; //从头节点开始查找
while (current != NULL) {
if (current->val == value) {
return current; //找到目标节点
}
current = current->next; //移到下一个节点继续查找
}
return NULL; //未找到目标节点
}
```
链表的销毁操作:
```c
void destroyList(ListNode* head) {
ListNode* current = head;
while (current != NULL) {
ListNode* temp = current;
current = current->next;
free(temp); //释放当前节点的内存空间
}
}
```
合并两个非递减的有序链表为一个非递增的有序链表:
```c
ListNode* mergeLists(ListNode* list1, ListNode* list2) {
ListNode* newHead = NULL; //合并后链表的头节点
ListNode* tail = NULL; //合并后链表的尾节点
while (list1 != NULL && list2 != NULL) {
if (list1->val <= list2->val) {
if (newHead == NULL) {
newHead = list1;
tail = list1;
} else {
tail->next = list1;
tail = tail->next;
}
list1 = list1->next;
} else {
if (newHead == NULL) {
newHead = list2;
tail = list2;
} else {
tail->next = list2;
tail = tail->next;
}
list2 = list2->next;
}
}
if (list1 != NULL) {
tail->next = list1; //将未插入的剩余节点接在尾节点之后
}
if (list2 != NULL) {
tail->next = list2; //将未插入的剩余节点接在尾节点之后
}
return newHead;
}
```
合并操作的示例:
```c
ListNode* list1 = createNode(3);
list1->next = createNode(6);
list1->next->next = createNode(8);
list1->next->next->next = createNode(9);
ListNode* list2 = createNode(2);
list2->next = createNode(5);
list2->next->next = createNode(8);
list2->next->next->next = createNode(10);
list2->next->next->next->next = createNode(12);
list2->next->next->next->next->next = createNode(16);
ListNode* mergedList = mergeLists(list1, list2);
```
注:以上代码仅供参考,实际应用中需要做额外的错误处理和内存释放。
阅读全文