编写C语言程序,实现两线性表的归并算法,采用不同存储结构进行算法实现并输出两者的运行时间。
要求:1. 已知线性表 LA=(3,5,8,11)和LB=(2,6,8,9,11,15,20),要求将LA与LB两线性表进行归并且仍保持元素有序
(相同元素要保留)。
2. 分别用顺序表和链表两种存储结构进行算法实现,并比较两者的运行时间等性能。
引用 皆我百晓生 小程序回复内容作答:
下面是使用顺序表和链表两种存储结构进行归并算法实现的 C 代码示例。代码注释中有详细的说明。
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
// 定义顺序表的最大长度
#define MAX_SIZE 20
// 定义线性表的结构体
typedef struct {
int data[MAX_SIZE];
int length;
} SeqList;
// 定义链表节点的结构体
typedef struct Node {
int data;
struct Node* next;
} ListNode;
// 初始化顺序表
void initSeqList(SeqList* L) {
L->length = 0;
}
// 初始化链表
ListNode* initLinkedList() {
ListNode* head = (ListNode*)malloc(sizeof(ListNode));
head->next = NULL;
return head;
}
// 在顺序表的指定位置插入元素
void insertSeqList(SeqList* L, int pos, int elem) {
if (pos < 0 || pos > L->length || L->length == MAX_SIZE) {
printf("Invalid position or SeqList is full.\n");
return;
}
for (int i = L->length - 1; i >= pos; i--) {
L->data[i + 1] = L->data[i];
}
L->data[pos] = elem;
L->length++;
}
// 在链表尾部插入元素
void insertLinkedList(ListNode* head, int elem) {
ListNode* new_node = (ListNode*)malloc(sizeof(ListNode));
new_node->data = elem;
new_node->next = NULL;
ListNode* curr = head;
while (curr->next != NULL) {
curr = curr->next;
}
curr->next = new_node;
}
// 对两个有序线性表进行归并
void merge(SeqList LA, SeqList LB, SeqList* LC) {
int i = 0, j = 0, k = 0;
while (i < LA.length && j < LB.length) {
if (LA.data[i] <= LB.data[j]) {
LC->data[k++] = LA.data[i++];
} else {
LC->data[k++] = LB.data[j++];
}
}
while (i < LA.length) {
LC->data[k++] = LA.data[i++];
}
while (j < LB.length) {
LC->data[k++] = LB.data[j++];
}
LC->length = k;
}
// 打印线性表中的元素
void printList(SeqList L) {
for (int i = 0; i < L.length; i++) {
printf("%d ", L.data[i]);
}
printf("\n");
}
// 释放链表内存
void freeLinkedList(ListNode* head) {
ListNode* curr = head;
ListNode* temp = NULL;
while (curr != NULL) {
temp = curr;
curr = curr->next;
free(temp);
}
}
int main() {
SeqList LA, LB, LC;
ListNode* head = NULL;
clock_t start_time, end_time;
initSeqList(&LA);
initSeqList(&LB);
initSeqList(&LC);
head = initLinkedList();
// 初始化线性表 LA 和 LB
insertSeqList(&LA, 0, 3);
insertSeqList(&LA, 1, 5);
insertSeqList(&LA, 2, 8);
insertSeqList(&LA, 3, 11);
insertSeqList(&LB, 0, 2);
insertSeqList(&LB, 1, 6);
insertSeqList(&LB, 2, 8);
insertSeqList(&LB, 3, 9);
insertSeqList(&LB, 4, 11);
insertSeqList(&LB, 5, 15);
insertSeqList(&LB, 6, 20);
// 对顺序表进行归并算法并测量运行时间
start_time = clock();
merge(LA, LB, &LC);
end_time = clock();
printf("Merged SeqList: ");
printList(LC);
printf("Time elapsed for SeqList: %f seconds.\n", (double)(end_time - start_time) / CLOCKS_PER_SEC);
// 对链表进行归并算法并测量运行时间
start_time = clock();
ListNode* curr = head;
for (int i = 0; i < LA.length; i++) {
insertLinkedList(curr, LA.data[i]);
curr = curr->next;
}
curr = head;
for (int i = 0; i < LB.length; i++) {
insertLinkedList(curr, LB.data[i]);
curr = curr->next;
}
printf("Merged LinkedList: ");
curr = head->next;
while (curr != NULL) {
printf("%d ", curr->data);
curr = curr->next;
}
printf("\n");
end_time = clock();
printf("Time elapsed for LinkedList: %f seconds.\n", (double)(end_time - start_time) / CLOCKS_PER_SEC);
freeLinkedList(head);
return 0;
}
这个程序首先定义了顺序表的结构体和链表节点的结构体,然后实现了初始化顺序表和链表、在指定位置插入元素、对两个有序线性表进行归并、打印线性表中的元素、释放链表内存等函数。
在 main
函数中,首先初始化线性表 LA 和 LB,然后调用归并函数 merge,在 merge 函数中将 LA 和 LB 归并到 LC 中。接着打印顺序表 LC 和测量顺序表归并算法的运行时间。
然后,使用链表实现归并算法。首先初始化一个带有头节点的链表,然后将 LA 和 LB 的元素依次插入到链表中,然后打印链表和测量链表归并算法的运行时间。
在程序最后,通过调用 freeLinkedList
函数释放链表内存。
你可以根据需要进行编译和运行,并比较顺序表和链表两种存储结构的运行时间等性能。
【以下回答由 GPT 生成】
首先,我们要明确线性表的归并算法的基本思想是将两个有序线性表合并成一个有序线性表。
对于顺序表的存储结构,我们可以使用两个指针分别指向 LA 和 LB 的起始位置,然后依次比较两个指针指向的元素大小,将较小的元素放入一个新的线性表 LC 中,并将对应的指针向后移动一位,直到其中一个线性表遍历完毕。最后,将剩余未遍历完的线性表中的元素放入 LC 中。
对于链表的存储结构,我们可以使用三个指针,分别指向 LA、LB 和 LC 的当前位置。其中 LA 和 LB 分别代表两个线性表的头节点,LC 代表新的线性表的头节点。通过比较 LA 和 LB 的元素大小,将较小的元素插入 LC 的尾部,并将对应的指针向后移动一位。当其中一个线性表到达尾部时,将另一个线性表的剩余部分直接连接到 LC 的尾部。
具体实现代码如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#define MAX_SIZE 100
typedef struct {
int data[MAX_SIZE];
int length;
} SeqList;
void InitList(SeqList *L) {
L->length = 0;
}
void Merge(SeqList LA, SeqList LB, SeqList *LC) {
int i = 0, j = 0, k = 0;
while (i < LA.length && j < LB.length) {
if (LA.data[i] <= LB.data[j]) {
LC->data[k++] = LA.data[i++];
} else {
LC->data[k++] = LB.data[j++];
}
}
while (i < LA.length) {
LC->data[k++] = LA.data[i++];
}
while (j < LB.length) {
LC->data[k++] = LB.data[j++];
}
LC->length = k;
}
int main() {
SeqList LA, LB, LC;
int i;
InitList(&LA);
InitList(&LB);
LA.data[0] = 3;
LA.data[1] = 5;
LA.data[2] = 8;
LA.data[3] = 11;
LA.length = 4;
LB.data[0] = 2;
LB.data[1] = 6;
LB.data[2] = 8;
LB.data[3] = 9;
LB.data[4] = 11;
LB.data[5] = 15;
LB.data[6] = 20;
LB.length = 7;
clock_t start_time, end_time;
double total_time;
start_time = clock();
Merge(LA, LB, &LC);
end_time = clock();
total_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;
printf("Merged List: ");
for (i = 0; i < LC.length; i++) {
printf("%d ", LC.data[i]);
}
printf("\nRunning time: %lf seconds\n", total_time);
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef struct Node {
int data;
struct Node *next;
} ListNode;
typedef struct {
ListNode *head;
ListNode *tail;
} LinkedList;
void InitList(LinkedList *L) {
L->head = NULL;
L->tail = NULL;
}
void Insert(LinkedList *L, int x) {
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
if (newNode == NULL) {
printf("Memory allocation failed.\n");
exit(1);
}
newNode->data = x;
newNode->next = NULL;
if (L->head == NULL) {
L->head = newNode;
L->tail = newNode;
} else {
L->tail->next = newNode;
L->tail = newNode;
}
}
void Merge(LinkedList LA, LinkedList LB, LinkedList *LC) {
ListNode *pa = LA.head;
ListNode *pb = LB.head;
ListNode *pc = NULL;
LC->head = NULL;
LC->tail = NULL;
while (pa != NULL && pb != NULL) {
if (pa->data <= pb->data) {
if (LC->head == NULL) {
LC->head = pa;
pc = pa;
} else {
pc->next = pa;
pc = pc->next;
}
pa = pa->next;
} else {
if (LC->head == NULL) {
LC->head = pb;
pc = pb;
} else {
pc->next = pb;
pc = pc->next;
}
pb = pb->next;
}
}
if (pa != NULL) {
pc->next = pa;
LC->tail = LA.tail;
}
if (pb != NULL) {
pc->next = pb;
LC->tail = LB.tail;
}
}
int main() {
LinkedList LA, LB, LC;
int i;
InitList(&LA);
InitList(&LB);
Insert(&LA, 3);
Insert(&LA, 5);
Insert(&LA, 8);
Insert(&LA, 11);
Insert(&LB, 2);
Insert(&LB, 6);
Insert(&LB, 8);
Insert(&LB, 9);
Insert(&LB, 11);
Insert(&LB, 15);
Insert(&LB, 20);
clock_t start_time, end_time;
double total_time;
start_time = clock();
Merge(LA, LB, &LC);
end_time = clock();
total_time = (double)(end_time - start_time) / CLOCKS_PER_SEC;
printf("Merged List: ");
ListNode *ptr = LC.head;
while (ptr != NULL) {
printf("%d ", ptr->data);
ptr = ptr->next;
}
printf("\nRunning time: %lf seconds\n", total_time);
return 0;
}
以上就是使用顺序表和链表两种存储结构实现对两个线性表的归并算法,并输出运行时间的详细过程和代码。尽量以清晰易懂的方式描述给出了每一步的具体操作。运行代码后,会先输出合并后的线性表的元素,然后输出程序运行的时间,单位为秒。
顺序表的实现使用了结构体和数组,链表的实现使用了结构体和指针,两种实现方式各有优缺点,在实际应用中可以根据具体情况选择适合的存储结构。
【相关推荐】