我最近收到了一个硬件,要求我合并k个排序的链表。老师建议的想法是将这些列表存储在堆中,然后简单地使用heapify。但是,即时消息处理指针和结构的时间很糟。这是我的代码,我会感激任何建议,超链接或更正,因为即时消息有点卡住了。 首先,我需要一些功能方面的帮助:createRandomList,createHeap,然后才是正确的合并。 PS:FillRandomArray是我的老师设计的用于随机填充数组的函数,因此它不应成为错误的来源。 谢谢!
typedef struct node {
int val;
struct node * next;
};
typedef struct list{
node *head;
};
list* createRandomList(int size) {
int *arr;
arr = (int*)malloc(size * sizeof(int));
list* myList = (list*)malloc(size * sizeof(list));
FillRandomArray(arr, size, 10, 500, false, 1);
for (int i = 0; i < size; i++) {
myList->head->val = arr[i];
cout << arr[i] << " next ";
if(i != size - 1)
myList->head = myList->head->next;
}
return myList;
}
list** createHeap(int k,int size) {
list* myList = (list*)malloc(size * sizeof(list));
list **heap = (list**)malloc(k * size * sizeof(list));
for (int i = 0; i < k; i++) {
cout << i;
heap[i] = createRandomList(size);
}
return heap;
}
void heapify(list** heap, int i, int size) {
}
list** buildHeap(list **heap, int k) {
}
bool checkHeap(list** heap, int k) {
for (int i = 0; i < k; i++) {
if (heap[i]->head == NULL)
return false;
else return true;
}
}
int* mergeSort(list** heap, int n, int k) {
int *sorted;
int i = 0;
sorted = (int*)malloc(n * k * sizeof(int));
list** minHeap = buildHeap(heap, k);
while (k > 0) {
if (checkHeap(minHeap, k) == TRUE) {
sorted[i] = minHeap[0]->head->val;
minHeap[0]->head = minHeap[0]->head->next;
i++;
}
else {
for (int j = 0; j < k; j++) {
if (minHeap[j]->head == NULL) {
k--;
delete(minHeap[k]);
for (int m = j; m < k; m++)
minHeap[m] = minHeap[m + 1];
}
}
}
minHeap = buildHeap(minHeap, k);
}
return sorted;
}
void main(){
int n, k;
cout << "Please enter the number of lists that you wish to have: ";
cin >> k;
cout << "\nNow please enter the number of elements that you wish your list to posses: ";
cin >> n;
cout << "\nThe lists to be merged are: ";
list **heap = (list**)malloc(k * n * sizeof(list));
heap = createHeap(k, n);
for (int i = 0; i < k; i++) {
for (int j = 0; j < n; j++) {
cout << heap[i]->head->val<<" ";
heap[i]->head = heap[i]->head->next;
}
cout << "\n";
}
}
答案 0 :(得分:0)
您的问题似乎是您不太了解如何使用列表。
代码行list* myList = (list*)malloc(size * sizeof(list));
为size
列表元素分配空间(或者返回一个指向size
列表数组的指针),而不是可以包含{{1 }}元素。
如果要分配size
元素的列表,可以使用以下代码。
size
代码如何工作?
注意:我们从列表的后面开始,这样我们就可以将新节点推到前面(两种方式都是可行的,但向前的方向需要一个附加的指针)。
您对list* listFromArray(int* a, size_t size) {
list* l = (list*)malloc(sizeof(list));
l->head = NULL;
node* current;
for (size_t i = 0; i < size; ++i) {
current = (node*)malloc(sizeof(node));
current->next = l->head;
current->val = a[size - i - 1];
l->head = current;
}
}
函数有类似的问题。
createHeap
由于您没有任何关于heapify的规范,因此我假设您的函数将采用未排序的列表数组,索引list** createHeap(int k,int size) {
list **heap = (list**)malloc(k * sizeof(*list)); // create array of k list pointers
for (int i = 0; i < k; i++) {
cout << i;
heap[i] = createRandomList(size); // populate ith entry with a random list
}
heapify(heap, k / 2, k); // turn unsorted array of lists into a heap of lists
return heap;
}
(不变,我之后的所有列表都是按堆顺序排列)和{{ 1}}的堆大小,并确保数组按堆顺序排列。
对于heapify,您可能想看看该函数应该做什么: https://medium.com/basecs/heapify-all-the-things-with-heap-sort-55ee1c93af82
主要思想是,我说过要从中点开始,并确保数组按堆顺序进行(我们知道大小为1的所有堆都是堆,因此我们可以从1/2点开始)。然后,我们从那里到数组的开头,将根在位置i
的堆的顶部“下沉”到正确的位置。注意:位置size
的元素的子元素是i
和i
。
您应该考虑您想要2 * i + 1
做的事情。我认为这应该是列表(最小)堆的含义。现在,您只需要检查堆中是否没有空列表即可。我认为空列表数组是按堆顺序排列的。并且列表的顺序应为字典顺序(按第一个元素,然后第二个,依此类推),特殊情况下,空列表为最高(最大元素)。
假设heapify如上所述工作,并且您有一个函数2 * (i + 1)
,它选择堆中的最低节点并将其从堆中删除,然后合并变得更加简单。
checkHeap