数据结构实验(四)
一、实验目的
1、复习线性表的逻辑结构、存储结构及基本操作;
2、掌握顺序表和(带头结点)单链表;
3、了解有序表。
二、实验内容
1、请采用顺序表或(带头结点)单链表实现:
(1)假设有序表中数据元素是正整数,请通过实现下列函数进而实现有序表的构造及归并:
(a) OrderInput(&L, int (*compare)(a, b))
//根据有序判定函数compare,并利用(b)中的有序插入函数OrderInsert,构造有序表L
(b) OrderInsert(&L, e, int (*compare)(a, b))
//根据有序判定函数compare,在有序表L的适当位置插入元素e
(c) OrderMerge(&La, &Lb, &Lc, int (*compare)())
//根据有序判定函数compare,将两个有序表La和Lb归并为一个有序表Lc
(2)请实现升幂多项式的构造及相加。升幂多项式是指多项式的各项按指数升序有序,约定系数不能等于0,指数不能小于0。
例如2-10x^2+3x^5或者 2-100x^14+3x^100-16x^1000
2、请实现:求一个顺序表序列的最长连续递增子序列,例如,{1,9,2,5,7,3,4,6,8,0}中的最长连续递增子序列为{3,4,6,8}
3、请实现:求两个单链表升序集合的交集,例如,{1,2,5}∩{2,4,5,8,10}={2,5}
三、数据结构及算法分析与设计
1.(1)数据结构:
链表节点结构体(ListNode)
data:存储节点的数据元素。
next:指向链表中下一个节点的指针。
链表结构体(LinkList)
head:指向链表的头结点,头结点不存储数据,用于简化插入和删除操作。
length:记录链表的长度,即节点的数量。
算法分析与设计:
1.初始化链表(InitList)
输入:链表指针。
输出:无。
2.创建新节点(CreateNode)
输入:数据元素e。
输出:新创建的节点指针。
3.打印链表(PrintList)
输入:链表指针。
输出:打印链表的所有数据元素。
4.有序输入(OrderInput)
输入:链表指针、比较函数指针。
输出:无。
5.有序插入(OrderInsert)
输入:链表指针、数据元素e、比较函数指针。
输出:无。
6.有序归并(OrderMerge)
输入:两个有序链表指针、结果链表指针、比较函数指针。
输出:无。
1.(2)数据结构: 多项式的项结构体(PolyNode)
coefficient:表示项的系数。
exponent:表示项的指数。
next:指向链表中下一个节点的指针。
算法分析与设计:
1.添加项(addTerm)
输入:多项式指针、系数、指数。
输出:无。
2.打印多项式(printPolynomial)
输入:多项式指针。
输出:打印多项式的每一项。
3.多项式相加(addPolynomials)
输入:两个多项式指针。
输出:返回相加后的多项式。
2.数据结构: 数组:
int arr[]:用于存储输入的顺序表序列。
int subsequence[]:用于存储最长连续递增子序列。
int subsequenceSize:用于存储子序列的大小。
算法分析与设计:
1.初始化:
设置 maxLength 为 1,因为单个元素本身就是一个递增子序列。
设置 currentLength 为 1,表示当前递增子序列的长度。
endIndex 用于记录最长递增子序列的结束索引。
2.遍历数组:
从第二个元素开始遍历数组。
若当前元素大于前一个元素,则递增 currentLength 并更新 subsequence。
若当前元素不大于前一个元素,则比较 currentLength 和 maxLength。
若 currentLength 大于 maxLength,则更新 maxLength 和 endIndex。
重置 currentLength 为 1,并更新 subsequence。
3.处理最后一个递增子序列:
遍历结束后,再次比较 currentLength 和 maxLength,以确保最后一个递增子序列被考虑。
4.复制最长递增子序列:
根据 endIndex 和 maxLength 计算最长递增子序列的起始索引。
将最长递增子序列复制到 subsequence 数组中。
3.数据结构:链表节点结构体(ListNode):
int val:存储节点的值。
ListNode* next:指向链表中下一个节点的指针。
算法分析与设计:
1.初始化:
创建两个链表的头节点 head1 和 head2。
创建一个哑节点 dummyHead 作为结果链表的头节点,以及一个指针 tail 指向结果链表的尾部。
2.遍历链表:
使用两个指针 p 和 q 分别遍历 head1 和 head2。
3.处理结束条件:
当p或q任一指针到达链表末尾时,结束遍历。
4.返回结果:
返回结果链表的头节点。
四、核心程序代码(给出必要注释)
1.(1)
int main() {
LinkList La, Lb, Lc;//定义三个有序表
//对有序表进行初始化
InitList(&La);
InitList(&Lb);
InitList(&Lc);
printf("请输入有序表La中的元素(输入-1结束):\n");
OrderInput(&La, ascendingCompare);
printf("请输入有序表Lb中的元素(输入-1结束):\n");
OrderInput(&Lb, ascendingCompare);
printf("有序表La: ");
PrintList(&La);
printf("有序表Lb: ");
PrintList(&Lb);
OrderMerge(&La, &Lb, &Lc, ascendingCompare);//调用函数进行归并
printf("有序表La和Lb归并为一个有序表Lc: ");
PrintList(&Lc);
return 0;
}
1.(2)
int main() {
Polynomial poly1, poly2, result; //定义多项式1、多项式2、相加的的结果
//初始化头指针
poly1.head = NULL;
poly2.head = NULL;
//多项式1添加系数和指数
addTerm(&poly1, 2, 0);
addTerm(&poly1, -10, 2);
addTerm(&poly1, 3, 5);
//多项式2添加系数和指数
addTerm(&poly2, 2, 0);
addTerm(&poly2, -100, 14);
addTerm(&poly2, 3, 100);
addTerm(&poly2, -16, 1000);
printPolynomial(&poly1);
printPolynomial(&poly2);
result = addPolynomials(&poly1, &poly2);
printf("两个多项式相加的结果是: ");
printPolynomial(&result);
return 0;
}
2.
int main() {
int arr[] = {1, 9, 2, 5, 7, 3, 4, 6, 8, 0};
int n = sizeof(arr) / sizeof(arr[0]);//记录数组元素个数
int subsequence[20]; // 假设最长递增子序列不会超过20个元素
int subsequenceSize = 0;
findLongestIncreasingSubsequence(arr, n, subsequence, &subsequenceSize);
printf("最长连续递增子序列是: ");
for (int i = 0; i < subsequenceSize; i++) {
printf("%d ", subsequence[i]);
}
return 0;
}
3.
int main() {
// 创建两个单链表
ListNode *list1 = createNode(1);
list1->next = createNode(2);
list1->next->next = createNode(5);
ListNode *list2 = createNode(2);
list2->next = createNode(4);
list2->next->next = createNode(5);
list2->next->next->next = createNode(8);
list2->next->next->next->next = createNode(10);
// 求交集
ListNode *intersectionList = intersection(list1, list2);
// 打印交集
printf("两个单链表升序集合的交集是:");
printList(intersectionList);
// 释放链表内存
while (intersectionList != NULL) {
ListNode *temp = intersectionList;
intersectionList = intersectionList->next;
free(temp);
}
return 0;
}
五、测试及结果(给出测试用例及测试结果)
1.(1)

1.(2)

2.

3.

更多推荐



所有评论(0)