基于双链表的Deque实现不起作用

时间:2014-01-22 04:54:28

标签: c++ c pointers data-structures struct

这是我使用双向链表实现deque的代码。它没有用。你能告诉我一些关于我出错的地方。指针未初始化,代码卡在addqatend函数中。

#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>

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

struct queue
{
struct node *front;
struct node *rear;
};


void initqueue(struct queue *);
void addqatbeg(struct queue *,int);
void addqatend(struct queue *, int);
int delqatbeg(struct queue *);
int delqatend(struct queue *);
void delqueue(struct queue *);

int main()
{
struct queue a;
int i;

system("cls");
initqueue(&a);

addqatbeg(&a,11);
addqatbeg(&a,23);
addqatbeg(&a,-5);
addqatbeg(&a,45);

addqatend(&a,34);
addqatend(&a,78);

i = delqatbeg(&a);
if(i!=NULL)
    printf("item deleted from front:%d",i);
i = delqatbeg(&a);
if(i!=NULL)
    printf("item deleted from front:%d",i);
i = delqatend(&a);
if(i!=NULL)
    printf("item deleted from end:%d",i);
i = delqatend(&a);
if(i!=NULL)
    printf("item deleted from end:%d",i);

delqueue(&a);

system("pause");
return 0;
}

//initialise the queue
void initqueue(struct queue *q)
{
q->front = q->rear = NULL;
}

//add at the beginning of the queue
void addqatbeg(struct queue *q,int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
    printf("queue is full\n");
//temp->data = item;
//temp->link = NULL;
if(q->front == NULL)
{
    q->rear = q->front = temp;
    q->front->prev = NULL;
    q->front->next = NULL;
    q->rear->next = NULL;
    q->rear->prev = NULL;
    return;
}


q->front->data = item;
q->front->next = temp;
q->front = temp;
q->front->prev = q->front;
//q->rear->next = q->front->next;
//q->front->prev = q->rear;
}

//add at the end of the queue
void addqatend(struct queue *q, int item)
{
struct node *temp;
temp = (struct node*)malloc(sizeof(struct node));
if(temp == NULL)
    printf("queue is full\n");
if(q->front == NULL)
{
    q->rear = q->front = temp;
    q->front->prev = NULL;
    q->front->next = NULL;
    return;
}
while(q->front->next!=NULL)
    q->rear = q->front->next;
q->rear->data = item;
q->rear->next =temp;
q->rear = q->rear->next;
q->rear->prev = q->rear;
 }

//delete at the beginning of the queue
int delqatbeg(struct queue *q)
{
struct node *temp;
int item;
if(q->front ==NULL)
{
    printf("queue is empty:\n");
    return NULL;
}
item = q->front->data;
temp = q->front;
q->front = q->front->next;
free(temp);
return item;
 }

//delete at the end of the queue
 int delqatend(struct queue *q)
{
struct node *temp;
int item;
if(q->rear == NULL)
{
    printf("queue is empty\n");
    return NULL;
}
item = q->rear->data;
temp = q->rear;
q->rear = q->rear->prev;
free(temp);
return item;
}

//free the nodes
 void delqueue(struct queue *q)
{
struct node *temp;

if(q->front == NULL)
    return;
while(q->front!=NULL)
{
    temp = q->front;
    q->front = q->front->next;
    free(temp);
}
}

2 个答案:

答案 0 :(得分:1)

这里有各种各样的问题。

#include <stdio.h>
#include <conio.h>
#include <iostream>
#include <string.h>
#include<time.h>
#include<math.h>
#include<ctype.h>
#include <malloc.h>
#include <Windows.h>

呃,这是一大堆包括在内的。你用的是什么语言?下定决心。 <iostream>是C ++标头,其余是C标头。什么是<malloc.c>?通常,malloc应位于<stdlib.h><windows.h>。对于此示例,您只需要<stdlib.h><stdio.h>

如果我打开编译器警告,我会收到有关比较和赋值指针整数的警告。在delqatend中,您应该返回普通0作为错误代码,而不是NULL。同样在这里:

i = delqatbeg(&a);
if (i != NULL) 
    printf("item deleted from front:%d", i);

NULL应为0。 (0是空指针和空整数的语言表示,但宏NULL将其转换为(void *),使其成为指针。此处为i是一个整数。)另外,请在字符串的末尾打印换行符。

temp = (struct node *) malloc(sizeof(struct node));
if (temp == NULL)
    printf("queue is full\n");

如果你的工作内存不足,我喜欢队列是如何填满的,但是你不应该只打印它,而是做其他事情,比如中止进程或返回错误代码,否则你以后会做些坏事。函数指向NULL

好的,现在你的主要问题。我们来看看你的函数addqatbeg。在队列为空的情况下,您可以正确插入节点,尽管您基本上执行了两次相同的分配,因为q->frontq->end相等。但是您没有将数据分配给新节点。

另一种情况是,队列中已经存在节点,这是一个混乱。你不是通过绕着他们的数据摇晃isert节点,而是通过指针重新组织队列结构。这是一个更好的addqatbeg

//add at the beginning of the queue
void addqatbeg(struct queue *q, int item)
{
    struct node *temp;

    // Create node and check for NULL
    temp = (struct node *) malloc(sizeof(struct node));

    if (temp == NULL) {
        printf("queue is full\n");
        return;
    }

    // Assign data
    temp->data = item;
    temp->prev = temp->next = NULL;

    // Insert node
    if (q->front == NULL) {
        q->rear = q->front = temp;
    } else {
        temp->next = q->front;
        q->front->prev = temp;
        q->front = temp;
    }
}

现在应该很容易实现addqatend。函数addqatendaddqatbeg在您的情况下完全类似,因为您保持向前和向后指针。 while中的addqatend循环非常丰富,并引入了无限循环:您检查q->front,但从不在循环中更新它。

答案 1 :(得分:0)

看看这些功能是否适合您。重复模式表明在常见函数中进行了一些重构,但试试这个。

Addqatbeg:

//add at the beginning of the queue
void addqatbeg(struct queue *q,int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
    printf("queue is full\n"); 

if(q->front == NULL)
{
    q->rear = q->front = temp;
    q->front->data = item;      
    return;
}
q->front->next = temp;
q->front = q->front->next;
q->front->data = item;    
}

Addqatend:

//add at the end of the queue
void addqatend(struct queue *q, int item)
{
struct node *temp;
temp = (struct node *)malloc(sizeof(struct node));
if(temp == NULL)
    printf("queue is full\n"); 

if(q->rear == NULL)
{
    q->rear = q->front = temp;
    q->rear->data = item;  
    return;
}
q->rear->prev = temp;    
q->rear = q->rear->prev;
q->rear->data = item;    
}

Delqatbeg:

//delete at the beginning of the queue
int delqatbeg(struct queue *q)
{
struct node *temp;
int item;

if(q->front == NULL)
{
    printf("queue is empty:\n");
    return NULL;
}

item = q->front->data;
    temp = q->front;
    q->front = q->front->prev;        
    free(temp);
}    
return item;
}

Delqatend:

//delete at the beginning of the queue
int delqatend(struct queue *q)
{
struct node *temp;
int item;

if(q->rear == NULL)
{
    printf("queue is empty:\n");
    return NULL;
}

    item = q->rear->data;
    temp = q->rear;
    q->rear = q->rear->next;        
    free(temp);
return item;
}