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

时间:2015-10-31 08:32:31

标签: c pointers linked-list queue

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

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

3 个答案:

答案 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是错误的内存地址。