嗨,大家好,我本周的实验室作业,我被分配了解链接列表。实验提示如下:
编写一个程序,创建一个至少包含20个元素的前向链接列表,其中每个元素包含一个0到99之间的随机整数。打印列表。
编写函数" returnMiddleList"在一次传递中找到链表的中间元素。打印此元素的整数值以及此元素的位置(从零开始)相对于头部(其中head = 0,head指向的元素= 1,前一个指向的元素= 2等等。)
将中间元素的列表分成两半,以创建两个完全独立的*相同大小(+/- 1)的链接列表并打印两个列表。修改" returnMiddleList"函数来实现这一点,返回第二个链表的头部,并将指向该头的元素的链接设置为null。然后打印存储在两个列表元素中的两个整数和。
将两个列表从最小到最大排序并打印出来(根据所采用的排序方法,此步骤的打印是可选的)。然后组合两个列表,同时从最小到最大排序它们并打印出新列表。 (提示:您可以进一步细分列表,并在排序和组合前两个未排序列表之前按一到两个元素列表的比例对它们进行排序。这种称为什么?)
我有#1和#2工作,但#3和#4是问题开始的地方。当我将链接列表拆分为两个列表并打印出单个列表时,我的第一个链接列表打印出9个数字,当它应该打印出10(第10个数字不知何故消失?),但是当我做第一个列表的总和时在那之后,已经消失的数字被添加到总和中!我不知道它为什么会消失,这是一个问题。另一个问题是在第二个列表中,一个随机的" 0"被添加到列表中,其中一个数字丢失。我的最后一个问题是#4,因为我使用的合并算法似乎不起作用(我在排序时将列表合并在一起,但我没有使用递归排序,因为我们还没有学到它)。任何输入和帮助将不胜感激!谢谢!
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
struct nodeType {
int data;
nodeType *link;
};
void populateList(nodeType *head) {
// srand(time(NULL));
nodeType *temp;
nodeType *current = head;
for (int i = 0; i < 20; i++) {
temp = new nodeType;
current->data = rand() % 100;
current->link = temp;
current = temp;
}
temp->link = NULL;
}
void print(nodeType *head) {
int i = 1;
while (head->link != NULL) {
cout << "#" << i++ << ": " << head->data << endl;
head = head->link;
}
}
nodeType* returnMiddleList(nodeType *head) {
nodeType *p1 = head, *p2 = head;
int count = 0;
int middle = 1;
while (p1->link->link != NULL) {
p1 = p1->link;
count++;
if (count % 2 == 0) {
p2 = p2->link;
middle++;
}
}
cout << "Middle #" << middle << ": " << p2->data << endl;
p1 = p2->link;
p2->link = NULL;
return p1;
}
void add(nodeType *head) {
int sum = 0;
while (head != NULL) {
sum = sum + head->data;
head = head->link;
}
cout << sum << endl;
}
void sort(nodeType *head) {
nodeType *temp = head;
while (temp != NULL) {
nodeType *temp2 = temp;
while (temp2 != NULL) {
if (temp->data > temp2->data) {
int temp3;
temp3 = temp->data;
temp->data = temp2->data;
temp2->data = temp3;
}
temp2 = temp2->link;
}
temp = temp->link;
}
}
nodeType* merge(nodeType* head1, nodeType* head2) {
nodeType *head3 = new nodeType, *current1 = head1, *current2 = head2;
while (current1 != NULL || current2 != NULL) {
if (current1 == NULL) {
while (current2 != NULL) {
//logic
current2 = current2->link; //dumps list 2
head3->data = current2->data;
}
break;
}
if (current2 == NULL) {
while (current1 != NULL) {
//Logic
current1 = current1->link; //dumps list 1
head3->data = current1->data;
}
break;
}
if (current1->data < current2->data) {
//logic
current1 = current1->link; //increments list 1
head3->data = current1->data;
} else {
//logic
current2 = current2->link; //increments list 2
head3->data = current2->data;
}
}
return head3;
}
int main() {
nodeType *head = new nodeType, *head2, *head3;
populateList(head);
print(head);
cout << endl;
head2 = returnMiddleList(head);
cout << endl << "List #1 Sum: ";
add(head);
cout << endl << "List #2 Sum: ";
add(head2);
sort(head);
cout << endl << "List #1 Sorted" << endl;
print(head);
sort(head2);
cout << endl << "List #2 Sorted" << endl;
print(head2);
head3 = merge(head, head2);
print(head3);
}
答案 0 :(得分:0)
对于#3,您不需要计数。在尝试检查p1-&gt;链接之前,代码还应包括对head == NULL,p1 == NULL的检查,并且在尝试检查p1-&gt; link-&gt之前应检查p1-&gt; link == NULL ;链接。在添加这些检查之后,为了消除计数,一次只增加p1两个:p1 = p1-> link-&gt; link,同时一次推进p2:p2 = p2-&gt; link。使用p1-&gt; link或p1-&gt; link-&gt;链接到达列表末尾后,请将p2视为指向列表前半部分的最后一个节点的指针,并按照给定的说明进行操作如何拆分列表。
对于#4,递归地将列表拆分成子列表的方法通常称为divide and conquer algorithm(wiki链接)。这种方法用于自顶向下合并排序,虽然还有其他方法更适合(更快)实现与链表的合并排序,但我得知教师可能希望您遵循给定的提示。