C语言链表实现双端队列:插入函数异常及显示功能问题排查
Let's walk through fixing your deque implementation step by step. There are several critical bugs in your code that are causing silent failures and incorrect behavior:
Key Bugs & Fixes
1. Incorrect Initialization in CreateDeQueue
Your original code assigns -1 (an integer) to dq->front and dq->rear, which are pointer types. This type mismatch corrupts pointer values and breaks empty queue checks.
Fixed code:
void CreateDeQueue(DeQueue *dq){ dq->count = 0; dq->full = FALSE; dq->front = dq->rear = NULL; // Initialize pointers to NULL, not -1 }
2. Broken InsertRear Logic
The else block in your InsertRear function had inverted logic and incorrect pointer assignments:
- You set
dq->rear = NULLright after linking the new node, which destroyed the deque's tail. np->next = npcreated a self-looping node, which is useless for a deque.- You assigned the entry value after linking the node (this should happen first).
Fixed code:
void InsertRear(DeQueueElement x, DeQueue *dq){ Node *np; np = (Node* )malloc(sizeof(Node)); if(np == NULL){ printf("Not enough space\n"); return; // Exit if malloc fails } np->entry = x; // Assign value first np->next = NULL; // New rear node has no next node if(dq->rear == NULL){ // Empty deque: both front and rear point to new node dq->front = dq->rear = np; np->prev = NULL; } else{ // Link new node to current rear np->prev = dq->rear; dq->rear->next = np; dq->rear = np; // Update rear to new node } dq->count++; // Track element count (useful for debugging) }
3. Typo in DeleteRear
You used a comparison operator (==) instead of an assignment (=) when clearing the front pointer after deleting the last element. This left a dangling front pointer.
Fixed code:
void DeleteRear(DeQueue *dq){ if(IsEmpty(dq)){ // Use your IsEmpty function for clarity printf("Underflow\n"); return; } Node *temp; temp = dq->rear; dq->rear = dq->rear->prev; if(dq->rear == NULL){ dq->front = NULL; // Correct assignment, not comparison } else{ dq->rear->next = NULL; } free(temp); dq->count--; }
4. Fixed display Function
Your original display function had wrong empty-check logic and skipped elements during traversal. The corrected version traverses from front to rear, printing all elements.
Fixed code:
void display(DeQueue *dq) { if (IsEmpty(dq)) { printf("Queue is empty\n"); return; } Node *temp = dq->front; printf("Deque elements (front to rear): "); while (temp != NULL) { printf("%d ", temp->entry); temp = temp->next; } printf("\n"); }
Complete Working Code
Here's the full corrected implementation with optional delete tests:
#include<stdio.h> #include<stdlib.h> typedef int DeQueueElement; typedef enum{FALSE,TRUE} Boolean; typedef struct node{ DeQueueElement entry; struct node *next, *prev; }Node; typedef struct dequeue{ int count; Boolean full; Node *front; Node *rear; }DeQueue; void CreateDeQueue(DeQueue *dq){ dq->count = 0; dq->full = FALSE; dq->front = dq->rear = NULL; } Boolean IsEmpty(DeQueue *dq){ return (dq->front == NULL && dq->rear == NULL); } Boolean IsFull(DeQueue *dq){ return(dq->full); } void InsertRear(DeQueueElement x, DeQueue *dq){ Node *np; np = (Node* )malloc(sizeof(Node)); if(np == NULL){ printf("Not enough space\n"); return; } np->entry = x; np->next = NULL; if(dq->rear == NULL){ dq->front = dq->rear = np; np->prev = NULL; } else{ np->prev = dq->rear; dq->rear->next = np; dq->rear = np; } dq->count++; } void InsertFront(DeQueueElement x, DeQueue *dq){ Node *np; np = (Node* )malloc(sizeof(Node)); if(np == NULL){ printf("Not enough space\n"); return; } np->entry = x; np->prev = NULL; // New front node has no previous node if(dq->front == NULL){ dq->rear = dq->front = np; np->next = NULL; } else{ np->next = dq->front; dq->front->prev = np; dq->front = np; } dq->count++; } void DeleteFront(DeQueue *dq){ if(IsEmpty(dq)){ printf("Underflow\n"); return; } Node *temp; temp = dq->front; dq->front = dq->front->next; if(dq->front == NULL){ dq->rear = NULL; } else{ dq->front->prev = NULL; } free(temp); dq->count--; } void DeleteRear(DeQueue *dq){ if(IsEmpty(dq)){ printf("Underflow\n"); return; } Node *temp; temp = dq->rear; dq->rear = dq->rear->prev; if(dq->rear == NULL){ dq->front = NULL; } else{ dq->rear->next = NULL; } free(temp); dq->count--; } void display(DeQueue *dq) { if (IsEmpty(dq)) { printf("Queue is empty\n"); return; } Node *temp = dq->front; printf("Deque elements (front to rear): "); while (temp != NULL) { printf("%d ", temp->entry); temp = temp->next; } printf("\n"); } int main(){ DeQueue dq; CreateDeQueue(&dq); InsertFront(21,&dq); InsertFront(1,&dq); InsertFront(221,&dq); InsertRear(23,&dq); InsertRear(36,&dq); display(&dq); // Optional test for delete functions printf("\nAfter deleting front: "); DeleteFront(&dq); display(&dq); printf("After deleting rear: "); DeleteRear(&dq); display(&dq); return 0; }
Notes
- The
IsFullfunction currently returns thefullflag which is never set. Since we're using dynamic memory allocation, the deque is only "full" whenmallocfails, so you could remove thefullfield and adjustIsFullto checkmallocsuccess during insertion. - I added increment/decrement of
countto track element count, which helps with debugging and validation. - Your delete functions now work correctly because the insertion and initialization logic is fixed.
内容的提问来源于stack exchange,提问作者user11231270

