Queues and stacks are a restricted linear table. So they all have the same way of realization. Prior to the implementation of chain stack and chain linear table experience, natural writing chain team, there is no problem.
Here is a detailed explanation of the technical points of each piece of code
Here is the data structure of the queue node
struct Queuenode{elementtype data; Queuenode * next;};/ /Generate a node Queuenode * queuenodemake (ElementType data) {Queuenode * Pnode = (Queuenode *) malloc (sizeof (Queuenode)); if (Pnode ! = null) {pnode->data = Data;pnode->next = null;} return pnode;}
The node structure of a queue, whether it is a linear table or a stack, is the classic structure of a data element and a successor pointer. (You can add a precursor to form two-way xxx).
Then there is a function that generates a node from the data element, which needs to be noted: 1. Memory allocation failure 2. Set the successor of the node to NULL to reduce the likelihood of errors.
Here is the data structure of the queue:
struct Linkqueue{queuenode * front;//head pointer queuenode * rear;//team tail int len;};
Front is the head pointer, whose successor is the team head node,
Rear points to the tail node of the team.
Len: Queue Length; This part of Len is a very good implementation, simplifying many operations and making logic clear. For example: 1.2 When judging if the queue is empty. Determines the length of the queue 3. When the queue is out, determine if the queues are empty.
But always keep in mind the change in Len's length: 1.1 2 When the team is out. When you queue, clear 3
Here is the Initialize queue function
E_state queueinit (Linkqueue * queue) {Queuenode * node = (Queuenode *) malloc (sizeof (Queuenode)); if (node = = NULL) {return E _state_error;} else{//the initial head node is NULL is important node->next = Null;queue->front = Queue->rear = Node;queue->len = 0;return E_State_Ok;}}
This function is simple, just pay attention to initialize the properties of the queue
Queue->front = queue->rear = Node;queue->len = 0;
and the successor setting of the head node is null.
It is important that the initial head node is null node->next = NULL;
Here is the empty queue function:
void Queueclear (Linkqueue * queue) {Queuenode * next = queue->front->next;while (next = NULL) {//order is important queuenode * fre Enode = Next;next = Next->next;free (freenode);} Resets the status of the empty queue queue->rear = Queue->front;queue->len = 0;}
Here are two parts to note when writing this function:
1. Release the order of the nodes, operation errors are likely to cause memory problems
Order is important queuenode * freenode = Next;next = Next->next;free (freenode);
2. Missing the state of the empty queue
queue->rear = Queue->front;queue->len = 0;
The following is the Destroy queue function
void Queuedestory (Linkqueue * queue) {queueclear (queue); free (queue->front); queue->front = Queue->rear = NULL;}
1. Empty Queue 2. Release the head node 3. Set pointer to null
Here are the empty and length functions
BOOL Queueempty (Linkqueue queue) {return Queue.len = = 0? true:false;} int Queuelen (Linkqueue queue) {return queue.len;}
Prove the benefits of the Len attribute
The queue and the team are the most difficult to write two functions. First, the function for the entry and exit team
Queue E_state enqueue (linkqueue * queue,elementtype data) {Queuenode * NewNode = queuenodemake (data);//Set the value of the new node and set the node successor to Nullif (NewNode! = NULL) {//The successor of the tail is set to a new node Queue->rear->next = newnode;//Set tail node queue->rear = newnode;queue-> len++;} return NewNode! = NULL? E_state_ok:e_state_error;}
Queuenode * NewNode = queuenodemake (data);//Set the value of the new node and set the successor of the node to NULL
This function simplifies the details of the queue (the successor of the tail of the queue is set to null)
Queue->rear = newnode;queue->len++;
At the end of a queue, point to the new node and the length +1
The details of the team are handled more than the queue.
Out Team E_state dequeue (linkqueue * queue,elementtype * top) {if (Queue->len! = 0) {Queuenode * Frontnode = queue->front-& gt;next;//point to Team head node Queue->front->next = frontnode->next;queue->len--;//error prone if (Frontnode = = Queue->rear )//out of the queue is the tail pointer, re-set the tail pointer {queue->rear = Queue->front;} Easy to miss Write *top = Frontnode->data;free (Frontnode); return E_STATE_OK;} else//empty Queue {return e_state_error;}}
Again, the logic of Len's clear and convenient line was proved.
Queuenode * Frontnode = queue->front->next;//point to Team head node Queue->front->next = frontnode->next;queue-> len--;
Set the successor of the head node to the successor of the Team head node and reduce the queue length by 1
Error prone if (Frontnode = = queue->rear)//out of the queue is the tail pointer, reset the tail pointer {queue->rear = Queue->front;}
Out of the queue is the tail pointer, you need to reset the tail pointer, or the tail pointer to a freed space. (Can change the condition to Queue->len = = 0, the good Len AH)
Easy to miss Write *top = Frontnode->data;free (Frontnode);
Returns the team header data, and frees the memory. Xtop = frontnode->data; This code is very likely to be missing.
And finally, the traversal queue function
void Queuetraverse (Linkqueue queue) {Queuenode * next = queue.front->next;printf ("---------queue traversal starts---------\ n"); while (next! = NULL) {printf ("---------%d---------\ n", next->data);//Easy to miss write Next = Next->next;} printf ("---------queue traversal ended---------\ n");}
It's easy, but this time I missed it. Next = next->next; , is the only mistake I've made in writing this piece of code.
After you finish writing the code, you need to check the code. Instead of waiting to find the problem, back again to check the problem.
The following is the complete code: (can be directly copied run)
Please note that the code is insufficient
LinkQueue.cpp: Defines the entry point of the console application. #include "stdafx.h" #include <stdlib.h>typedef int elementtype;enum e_state{e_state_error = 0,e_state_ok,}; struct Queuenode{elementtype data; Queuenode * next;};/ /Generate a node Queuenode * queuenodemake (ElementType data) {Queuenode * Pnode = (Queuenode *) malloc (sizeof (Queuenode)); if (Pnode ! = null) {pnode->data = Data;pnode->next = null;} return pnode;} struct Linkqueue{queuenode * front;//head pointer queuenode * rear;//team tail int len;}; E_state queueinit (Linkqueue * queue) {Queuenode * node = (Queuenode *) malloc (sizeof (Queuenode)); if (node = = NULL) {return E _state_error;} else{//the initial head node is NULL is important node->next = Null;queue->front = Queue->rear = Node;queue->len = 0;return E_State_Ok;}} void Queueclear (Linkqueue * queue) {Queuenode * next = queue->front->next;while (next = NULL) {//order is important queuenode * fre Enode = Next;next = Next->next;free (freenode);} Resets the status of the empty queue queue->rear = Queue->front;queue->len = 0;} void Queuedestory (Linkqueue * queue) {queueclear (qUeue); free (queue->front); queue->front = Queue->rear = NULL;} BOOL Queueempty (Linkqueue queue) {return Queue.len = = 0? true:false;} int Queuelen (Linkqueue queue) {return queue.len;} Queue E_state enqueue (linkqueue * queue,elementtype data) {Queuenode * NewNode = queuenodemake (data);//Set the value of the new node and set the node successor to Nullif (NewNode! = NULL) {//The successor of the tail is set to a new node Queue->rear->next = newnode;//Set tail node queue->rear = newnode;queue-> len++;} return NewNode! = NULL? E_state_ok:e_state_error;} Out Team E_state dequeue (linkqueue * queue,elementtype * top) {if (Queue->len! = 0) {Queuenode * Frontnode = queue->front-& gt;next;//point to Team head node Queue->front->next = frontnode->next;queue->len--;//error prone if (Frontnode = = Queue->rear )//out of the queue is the tail pointer, re-set the tail pointer {queue->rear = Queue->front;} Easy to miss Write *top = Frontnode->data;free (Frontnode); return E_STATE_OK;} else//empty Queue {return e_state_error;}} void Queuetraverse (Linkqueue queue) {Queuenode * next = queue.front->next;printf ("---------queue traversal starts---------\ n"); while (next ! = NULL) {printf ("---------%d---------\ n", next->data);//Easy to miss write Next = Next->next;} printf ("---------queue traversal ended---------\ n");} int _tmain (int argc, _tchar* argv[]) {linkqueue queue;queueinit (&queue); int len = 10; ElementType Data;enqueue (&queue,1);//Queue dequeue (&queue,&data);//Team Queueclear (&queue);//Empty for (int i = 1; I <= Len; i++) {enqueue (&queue,i);} Queuetraverse (queue); char * empty = Queueempty (queue)? "NULL": "NOT NULL";p rintf ("Queue Length%d, queue is empty:%s", Queuelen (queue), empty); Queuedestory (&queue); return 0;}
Run
Look at the data structure write code (15) The implementation of chain-type queue