我需要一些逻辑帮助,我需要从链表创建一个队列。所以我从问题中得到了所有这些代码:
typedef struct _listnode
{
int item;
struct _listnode *next;
} ListNode; // You should not change the definition of ListNode
typedef struct _linkedlist
{
int size;
ListNode *head;
} LinkedList; // You should not change the definition of LinkedList
typedef struct _queue
{
LinkedList ll;
} Queue;
通过使用enqueue,dequeue和isEmptyQueue,我应该从链表创建一个队列。
所以我得到的逻辑是:
Loop thru list size
enqueue linked list head node
removeNode to update linkedlist head node
这个逻辑是否正确?我需要一个良好的开端,并提前感谢。
所以我已经发布了这个代码来从链表创建一个队列:
然而,它崩溃我的程序没有错误消息。我尝试使用虚值enqueue(q,1)并且它仍然崩溃。有什么想法吗?
答案 0 :(得分:1)
我认为你的逻辑是正确的,但我会添加更多细节,以便更容易编码
Loop through the link list, selecting nodes one by one (until NULL)
select a node;
enqueue the value to the queue;
Free the memory of that enqueued node;
adjust the pointers to point to the next node in the linked list;
修改强>
让我们详细编写算法
while(head != NULL)
//Loop to traverse the linked list, just as you would while displaying each node
enqueue( que, head->item);
//This function will work just like a normal enqueue() function
//It should take the item, and insert it in the queue and nothing else
//I would recommend use an array for the queue
temp = head; //save the current node address to free later
head = head -> next; //go to next node in the linked list
free(temp); //free the previous node
答案 1 :(得分:1)
说实话,我什么都不懂。
您无需将链接列表转换为队列。您所需要的只是使用列表初始化队列的数据成员ll
。
这是一个示范程序
#include <stdlib.h>
#include <stdio.h>
typedef struct _listnode
{
int item;
struct _listnode *next;
} ListNode; // You should not change the definition of ListNode
typedef struct _linkedlist
{
int size;
ListNode *head;
} LinkedList; // You should not change the definition of LinkedList
int insert( LinkedList *ll, int index, int value )
{
if ( index < 0 || index > ll->size ) return -1;
ListNode *tmp = malloc( sizeof( ListNode ) );
tmp->item = value;
if ( ll->head == NULL )
{
tmp->next = ll->head;
ll->head = tmp;
}
else
{
ListNode *current = ll->head;
while ( --index ) current = current->next;
tmp->next = current->next;
current->next = tmp;
}
++ll->size;
return 0;
}
void list_output( const LinkedList *ll )
{
for ( ListNode *current = ll->head; current != NULL; current = current->next )
{
printf( "%d ", current->item );
}
printf( "\n" );
}
typedef struct _queue
{
LinkedList ll;
} Queue;
void queue_output( const Queue *q )
{
list_output( &q->ll );
}
int main( void )
{
LinkedList lst = { 0, 0 };
const int N = 10;
for ( int i = 0; i < N; i++ ) insert( &lst, i, i );
list_output( &lst );
Queue q = { lst };
lst = ( LinkedList ) { 0, 0 };
queue_output( &q );
// call here the method that free allocated memory of the queue
return 0;
}
它的输出是
0 1 2 3 4 5 6 7 8 9
0 1 2 3 4 5 6 7 8 9
这就是队列现在是已分配节点的所有者。该列表依次为空。
这意味着您确实已将列表转换为队列。
如果您要将列表的元素复制到队列中(与转换操作相比,它是一个不同的操作),那么逻辑如下
遍历列表的方式与遍历它以输出其元素的方式相同,并为列表节点的每个数据值调用队列的enqueue
方法
for ( ; head != NULL; head = head->next )
{
enqueue( que, head->x );
}
列表本身将保持不变。
如果需要在复制操作后删除列表中的节点,则可以调用执行此操作的列表方法。
考虑到无需动态分配列表或队列。例如,列表的声明可能看起来像
typedef struct _linkedlist
{
int size;
ListNode *head;
} LinkedList; // You should not change the definition of LinkedList
LinkedList lst = { 0, 0 };
列表的节点是动态分配的。
同样适用于队列。
您可以按以下方式声明队列
typedef struct _queue
{
LinkedList ll;
} Queue;
Queue q = { { 0, 0 } };
如果您有一个列表然后将其转换为队列,那么写
就足够了q.ll = lst;
lst = ( LinkedList ) { 0, 0 };
也是这种方法
void enqueue(Queue *que, int x)
{
int counter = 0;
insert(&(que->l), counter++, x);
}
没有意义。此外,队列没有数据成员l
。它有数据成员ll
您需要将节点附加到队列。因此,您必须使用队列的数据成员size
的值作为必须插入新元素的索引。
所以方法看起来应该是
void enqueue( Queue *que, int x )
{
insert( &que->ll, que->ll.size, x) ;
}
答案 2 :(得分:0)
void createQFrmLl(LinkedList *ll, Queue * q)
{
while (ll->size)
{
enqueue(q, ll->head->item); <-- CHANGE done here (passing 'q' instead of &q)
removeNode(ll, 0);
}
}
enqueue()期待&#39;队列*&#39;但是你正在传递队列**&#39;因此,在enqueue()中解除引用q-&gt; ll正在崩溃,因为q是错误的内存地址。