在C

时间:2016-01-14 14:27:37

标签: c queue

我正在尝试编写一个入队,出队,删除所选号码并打印列表的程序。我有一个问题,我认为是因为菜单部分,当你写一个数字,我试图修复它,但它删除了最后一个数字,而不是第一个。打印显示错误的数字,当我尝试解决该问题时,我遇到了与出列时相同的问题。删除中有些错误,但我无法弄明白。

我感谢所有得到的帮助

编辑: 我已经改变了很多,现在其他一切都有效,除了删除。我想删除以找到我输入的号码并将其删除。

queue.c

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

struct node
{
    int info;
    struct node *ptr;
    int next;
}*first, *last, *temp, *first1;




void enq(int data);
void deq();
void empty();
void display();
void create();
void delete_queue();

int count = 0;

void main()
{
    int no, ch;

    printf("\n 1 - Enqueue");
    printf("\n 2 - Dequeue");
    printf("\n 3 - Delete");    
    printf("\n 4 - Display");
    printf("\n 5 - Exit");
    create();
    while (1)
    {
        printf("\n Enter choice : ");
        scanf_s("%d", &ch);
        switch (ch)
        {
        case 1:
            printf("Enter data : ");
            scanf_s("%d", &no);
            enq(no);
            break;
        case 2:
            deq();
            break;
        case 3:
            printf("Enter data : ");
            scanf_s("%d", &no);
            delete_queue(no);   
        case 4:
            display();
            break;
        case 5:
            exit(0);

        default:
            printf("Wrong choice, Please enter correct choice  ");
            break;
        }
    }
}


void create()
{
    first = last = NULL;
}


void enq(int data)
{
    if (last == NULL)
    {
        last = (struct node *)malloc(1 * sizeof(struct node));
        last->ptr = NULL;
        last->info = data;
        first = last;
    }
    else
    {
        temp = (struct node *)malloc(1 * sizeof(struct node));
        last->ptr = temp;
        temp->info = data;
        temp->ptr = NULL;

        last = temp;
    }
    count++;
}


void display()
{
    first1 = first;

    if ((first1 == NULL) && (last == NULL))
    {
        printf("Queue is empty");
        return;
    }
    while (first1 != last)
    {
        printf("%d ", first1->info);
        first1 = first1->ptr;
    }
    if (first1 == last)
        printf("%d", first1->info);
}

void deq()
{
    first1 = first;

    if (first1 == NULL)
    {
        printf("\n Error: Trying to display elements from empty queue");
        return;
    }
    else
        if (first1->ptr != NULL)
        {
            first1 = first1->ptr;
            printf("\n Dequed value : %d", first->info);
            free(first);
            first = first1;
        }
        else
        {
            printf("\n Dequed value : %d", first->info);
            free(first);
            first = NULL;
            last = NULL;
        }
    count--;
}



void delete_queue()
{
    int retval = -1;
    if (first)
    {
        struct node *temp = first;
        first = first->next;
        if (!first) { last = first; }
        retval = temp->next;
        free(temp);
    }
    return retval;
}
void empty()
{
    if ((first == NULL) && (last == NULL))
        printf("\n Queue empty");
    else
        printf("Queue not empty");
}

1 个答案:

答案 0 :(得分:2)

首先,我要谈谈有关设计和风格的几点建议:

我不推荐这个:

typedef struct node {
    int data;
    struct node *next;
} node;

您正在键入struct nodenode。虽然它不违法,但令人困惑。我会推荐

typedef struct _node {
    int data;
    struct _node *next;
} node;

此外,我不建议使用带有static存储类的全局变量来跟踪您的队列,而应该在main中创建一个队列。仅在有令人信服的理由时才使用全局变量。

请记住,当您摆脱全局变量时,您需要重写enqueue dequeue delete等...函数以接收queue_c *作为参数(因为它不再能够访问queueref

现在因为你的代码工作不正常而且@Weather Vane提到:

你的删除功能有一个大问题。

int delete(int data) 
{
    int result = 0;

    node *curr_ptr; //pointer just created and not initialized
    node *prev_ptr; //not initialized
    node *temp_ptr; //not initialized

    while (curr_ptr != NULL) 
    //curr_ptr was just created, where is it pointing? fatal error here
    {
    //inside this block lets imagine curr_ptr is pointing to a valid
    //node in the global queue

        if (curr_ptr->data == data) 
        {
            result = 1;
            if (curr_ptr->next != NULL) 
            {
                temp_ptr = curr_ptr;  
                //both pointers point to the same thing
                destroy_node(temp_ptr); 
                //now you just destroyed both nodes
                prev_ptr->next = curr_ptr->next;
                //the first time this block runs prev_ptr is uninitialized
                //so prev_ptr->next will most likely seg fault
                //this happens for example if you call this function
                //for the first time with a long queue    
            }
            else 
            {
                temp_ptr = curr_ptr;
                queueref.last = prev_ptr; 
                prev_ptr->next = NULL;
                destroy_node(temp_ptr); 
                //again you are destroying both curr_ptr and temp_ptr
            }
        }
        curr_ptr = curr_ptr->next;   
        prev_ptr = prev_ptr->next;
        return result;
    }
}

如果你仔细考虑边缘情况并从头开始重新思考一些逻辑,也许会更好。 (随时测试边缘情况)