【问题标题】:How I sort list with enqueue function in c?如何在c中使用入队函数对列表进行排序?
【发布时间】:2014-05-23 08:58:04
【问题描述】:

我的清单:

list= C,3 -->C,5,---> A,7 --> A,5 --> G,2--> C,11 -->A,4

我的输出:

output= C,5  C,11 G,2 A,7 A,4 A,5 C,3

但是有一些错误。我像在答案中一样编写代码,然后编写 charcmp 函数并用 strcmp 替换为 charcmp。它有时会正常工作。但通常第一个元素在错误的位置。我的排序​​代码喜欢答案的代码

【问题讨论】:

  • name 字段不可能是一个简单的 char 并且仍然支持像 "Kill""Bill" 这样的名称。它必须是char *char name[32];(或其他一些合理的大小)。我知道这是一个错字,但由于保留给定的struct 对您来说似乎很重要,因此应该更正它。
  • 是的,你是对的,它是我立即编辑的 char *name :)

标签: c data-structures queue


【解决方案1】:

试试这个:-

#include<stdio.h>
#include<stdlib.h>
/*Queue has five properties. capacity stands for the maximum number of elements Queue can hold.
  Size stands for the current size of the Queue and elements is the array of elements. front is the
 index of first element (the index at which we remove the element) and rear is the index of last element
 (the index at which we insert the element) */
typedef struct Queue
{
        int capacity;
        int size;
        int front;
        int rear;
        int *elements;
}Queue;
/* crateQueue function takes argument the maximum number of elements the Queue can hold, creates
   a Queue according to it and returns a pointer to the Queue. */
Queue * createQueue(int maxElements)
{
        /* Create a Queue */
        Queue *Q;
        Q = (Queue *)malloc(sizeof(Queue));
        /* Initialise its properties */
        Q->elements = (int *)malloc(sizeof(int)*maxElements);
        Q->size = 0;
        Q->capacity = maxElements;
        Q->front = 0;
        Q->rear = -1;
        /* Return the pointer */
        return Q;
}
void Dequeue(Queue *Q)
{
        /* If Queue size is zero then it is empty. So we cannot pop */
        if(Q->size==0)
        {
                printf("Queue is Empty\n");
                return;
        }
        /* Removing an element is equivalent to incrementing index of front by one */
        else
        {
                Q->size--;
                Q->front++;
                /* As we fill elements in circular fashion */
                if(Q->front==Q->capacity)
                {
                        Q->front=0;
                }
        }
        return;
}
int front(Queue *Q)
{
        if(Q->size==0)
        {
                printf("Queue is Empty\n");
                exit(0);
        }
        /* Return the element which is at the front*/
        return Q->elements[Q->front];
}
void Enqueue(Queue *Q,int element)
{
        /* If the Queue is full, we cannot push an element into it as there is no space for it.*/
        if(Q->size == Q->capacity)
        {
                printf("Queue is Full\n");
        }
        else
        {
                Q->size++;
                Q->rear = Q->rear + 1;
                /* As we fill the queue in circular fashion */
                if(Q->rear == Q->capacity)
                {
                        Q->rear = 0;
                }
                /* Insert the element in its rear side */ 
                Q->elements[Q->rear] = element;
        }
        return;
}
int main()
{
        Queue *Q = createQueue(5);
        Enqueue(Q,1);
        Enqueue(Q,2);
        Enqueue(Q,3);
        Enqueue(Q,4);
        printf("Front element is %d\n",front(Q));
        Enqueue(Q,5);
        Dequeue(Q);
        Enqueue(Q,6);
        printf("Front element is %d\n",front(Q));
}

【讨论】:

  • 但是在我的代码中,有一个名称是节点的结构,看起来:
  • 结构节点{ int age;字符名称;结构节点 *nextPtr; }
  • 谢谢,但我必须做一些不同的事情,比如你的代码:/我不知道
  • @DDave 您的代码与 OP 的问题不匹配。他正在尝试编写优先级队列,而不是队列。
【解决方案2】:

下面的代码应该可以完成这项工作。它将按年龄递增的顺序添加到列表中:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct _node_t {
    int age;
    char *name;
    struct _node_t *nextPtr;
} node_t;

node_t *node;

void enqueue(char *name, int age)
{
    node_t *p, *prev, *n;
    /* if empty list create first element and return */
    if (node == NULL)
    {
        node = (node_t *)malloc(sizeof(node_t));
        node->nextPtr = NULL;
        node->name = (char *)malloc(strlen(name) + 1);
        strcpy(node->name, name);
        node->age = age;
        return;
    }
    p = prev = node;
    /* search last element or element with superior age value */
    while((p->nextPtr != NULL) && strcmp(p->name, name) < 0)
    {
        prev = p;
        p = p->nextPtr;
    }
    if (strcmp(p->name, name) == 0)
    {
        while((p->nextPtr != NULL) && p->age < age)
        {
            prev = p;
            p = p->nextPtr;
        }
    }
    /* create the new element and store the data */
    n = (node_t *)malloc(sizeof(node_t));
    n->name = (char *)malloc(strlen(name) + 1);
    strcpy(n->name, name);
    n->age = age;
    /* insert the new element */
    if ((strcmp(p->name, name) < 0) || (strcmp(p->name, name) == 0 && p->age < age))
    {
        n->nextPtr = p->nextPtr;
        p->nextPtr = n;
    }
    else
    {
        n->nextPtr = p;
        if (prev->nextPtr == p)
        {
            prev->nextPtr = n;
        }
        else if (node == p)
        {
            node = n;
        }
    }
}

void printNodes()
{
    node_t *p;
    p = node;
    while(p != NULL)
    {
        printf("%s, %d\n", p->name, p->age);
        p = p->nextPtr;
    }
}

int main(int argc, char **argv)
{
    node = NULL;
    enqueue("Kill", 15);
    enqueue("Bill", 2);
    enqueue("Kill", 7);
    printNodes();

    return 0;
}

所以添加以下内容:

enqueue("Kill", 15);
enqueue("Bill", 2);
enqueue("Kill", 7);

将按照printNodes()打印的顺序存储:

Bill, 2
Kill, 7
Kill, 15

更新:

添加了姓名排序,然后是年龄。

【讨论】:

  • OP 想要的不仅仅是年龄顺序。
  • 但我无法按名称排序:/
  • 请给我一些排序名称的建议。我可以使用 strcmp 吗? @BLUEPIXY 和 daouzli
  • @user 是的,你使用 strcmp
  • 我可以知道为什么我有-1吗?我说是按年龄分类的。 OP 不清楚,并谈到了两个用于排序的结构,而只有一个结构!如果它不完全符合预期,它至少完成了部分工作并且可以更新!
【解决方案3】:

使用双指针的解决方案可能是最好的。您在技术上实现了优先级队列,而不是列表。您通过保持一个已排序的链表来实现它。优先队列上的出队操作将从列表中删除第一项。

因为这是我为你布置的家庭作业,但你需要完成其余的,这样你才能真正学习重要的东西。

EXIT CONDITION HERE -> 当您找到要插入的项目时,您要在此处检查。编写此条件,以便在发生这种情况时退出循环。

编辑 ^^ -> 当我说您将在我的意思之后插入的项目时,您当前正在查看的项目是第一个比 temp“更大”的项目。 queue 将指向指向该项目的下一个指针。我还在代码中添加了一行,使 set temp's next 指向该项目。当您更新*queue 时,您是说您想让上一个项目上的下一个指针指向*temp

在此处更新指针 -> 在此处更新 queue 以指向列表/队列中下一个人的下一个指针。

typedef struct Person {
   char name[20];
   int age;
   struct Person *next;
} Person;

void enqueue(Person **queue, char *name, int age) {
   Person *temp = calloc(1, sizeof(Person));
   strncpy(temp->name, name, 20);
   temp->age = age;

   while (*queue && "EXIT CONDITION HERE")
      //update the pointer here;

   temp->next = *queue; //forgot this line originally. You need it!!
   *queue = temp; //.this sets the next pointer of last item or head to temp
}


...

Person *queue = NULL;
enqueue(&queue, "Bob", 10);
enqueue(&queue, "John", 5);

Then print the list to check that enqueue works correctly.

【讨论】:

  • 谢谢它很有帮助,但我不明白一件事。我的老师对你的入队函数的标题说必须是这样的:void enqueue(char name, int age);
  • 列表是否保存在全局变量中?如果是这样,请改用它。您可以简单地写Person **queue = &amp;GLOBAL_VARIABLE; 并使用我所拥有的。
  • @user3668199 另外,如果结构中有 char *name,则还需要为其分配 malloc 空间并将 name 参数复制进去。如果保证,可以将其设置为等于参数传递一个字符串常量(例如 enqueue("Bob", 10))。在其他情况下,名称参数可能会被释放,或者如果它是静态字符串(在堆栈上)超出范围,因此您需要进行复制。
  • @user3668199 我对原来的内容进行了编辑。在开始之前,您应该阅读我写的内容,因为我最初给您的内容会导致一些问题。对此我深表歉意。
猜你喜欢
  • 2013-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-16
  • 1970-01-01
  • 2023-02-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多