一、实验目的
掌握线性表的链式存储结构及其基本操作。
二、实验内容
1、实现单链表的就地逆置。
2、建立两个非递减有序单链表,然后合并成一个非递减链表。
3、建立两个非递减有序单链表,然后合并成一个非递增链表。
4、编写一个主函数,调试上述算法。
三、功能(函数)设计
根据实验内容,我们可以将功能划分为三个模块,具体如下:
就地逆置模块:包括一个reverseList函数,用于就地逆置单链表。
非递减合并模块:包括一个mergeListInc函数,用于合并两个非递减有序单链表。
非递增合并模块:包括一个mergeListDec函数,用于合并两个非递增有序单链表。
四、程序设计
1. 就地逆置模块:
函数名称:ListNode* reverseList(ListNode* head)
ListNode* reverseList(ListNode* head) {
ListNode* pre = NULL;
ListNode* cur = head;
while (cur != NULL) {
ListNode* next = cur->next;
cur->next = pre;
pre = cur;
cur = next;
}
return pre;
}
函数功能:将给定的单链表就地逆置。
2. 非递减合并模块:
函数名称:ListNode* mergeListInc(ListNode* l1, ListNode* l2)
ListNode* mergeListInc(ListNode* l1, ListNode* l2) {
ListNode dummy;
dummy.next = NULL;
ListNode* cur = &dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->data <= l2->data) {
cur->next = l1;
l1 = l1->next;
}
else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = (l1 != NULL ? l1 : l2);
return dummy.next;
}
函数功能:将给定的两个非递减有序单链表合并成一个非递减有序单链表。
3. 非递增合并模块:
函数名称:ListNode* mergeListDec(ListNode* l1, ListNode* l2)
ListNode* mergeListDec(ListNode* l1, ListNode* l2) {
ListNode dummy;
dummy.next = NULL;
ListNode* cur = &dummy;
while (l1 != NULL && l2 != NULL) {
if (l1->data >= l2->data) {
cur->next = l1;
l1 = l1->next;
}
else {
cur->next = l2;
l2 = l2->next;
}
cur = cur->next;
}
cur->next = (l1 != NULL ? l1 : l2);
return dummy.next;
}
函数功能:将给定的两个非递增有序单链表合并成一个非递增有序单链表。
程序流程图如下:
五、运行与测试
1、测试数据及结果:
就地逆置单链表测试数据及结果:
原始链表:1 2 3 4
就地逆置后的链表:4 3 2 1
合并两个非递减有序单链表测试数据及结果:
非递减单链表l1:1 3 5
非递减单链表l2:2 4 6
合并后的非递减单链表:1 2 3 4 5 6
合并两个非递增有序单链表测试数据及结果:
非递增单链表l1:5 3 1
非递增单链表l2:6 4 2
合并后的非递增单链表:6 5 4 3 2 1
2、运行与测试期间遇到的问题及其解决办法:
在编写程序时,由于链表操作需要涉及到节点的创建、删除、插入等复杂操作,因此在代码实现过程中容易出现内存泄漏、指针错误等问题。为了避免这些问题,我们应该要仔细检查每个节点的指针,确保它们指向正确,同时在使用完节点后及时释放内存资源,以避免内存泄漏问题的发生。调试时,可以使用gdb等调试工具进行断点调试,以便快速定位和解决问题。