c-将链表转换为队列(移动节点)



我需要一些关于逻辑的帮助,我需要从链表中创建一个队列。所以我得到了问题中的所有这些代码:

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),但它仍然崩溃。有什么想法吗?

我认为您的逻辑是正确的,但我会添加更多细节,使代码更容易编写

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

说实话,我什么都不懂。

您不需要将链接列表转换为队列。您只需要使用列表初始化队列的数据成员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) ;
}
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()应为"Queue*",但您传递的是"Queue**",因此,在enqueue()内部取消引用q->ll将崩溃,因为q是错误的内存地址。

相关内容

  • 没有找到相关文章

最新更新