顺序队列是一种只能在一头进和另一头出的数据结构,所以结构体里设2个指针分别指向头部和尾部,用数组来存储数据。
1 #define MAXSIZE 1024 2 3 typedef int elemtype; 4 5 typedef struct SequenQueue{ 6 elemtype date[MAXSIZE]; 7 int front; 8 int rear; 9 }SequenQueue; 10 11 SequenQueue *init_SequenQueue(){ 12 13 SequenQueue *p = (SequenQueue *)malloc(sizeof(SequenQueue)); 14 if(p == NULL){ 15 printf("创建失败"); 16 return NULL; 17 } 18 19 20 p->front = 0; 21 p->rear = 0; 22 return p; 23 24 }
顺序队列会有一种假溢出的现象:当元素进队或出队的时候,front或rear会加一,在一个数组中,两个指针都在向数组后面移动,直到它俩到达了数组尾部,但前面就会空出未使用的位置。解决方法就是取余运算,把它当做循环队列。
进队的运算:p->rear = (p->rear+1) % MAXSIZE
出队的运算:p->front = (p->front+1) % MAXSIZE
假设数组长度为6,开始时front和rear都指向0,进队ABCD四个元素,再进队EF元素,rear指向下标为0的位置,出队AB元素front指向C元素。再进队GH元素使rear和front在同一位置,此时队满但却发现front==rear不能作为队空的判断条件。应对方法有2种:一种为少使用一个位置,如上图d所示。判断队满的条件为(p->rear+1) % MAXSIZE) == (p->front % MAXSIZE)(右边取余运算可省略)。另一种是用计数器的方法,入队加一出队减一,一直加到数组的最大长度即为满。
1 int SequenQueue_Full(SequenQueue *p){ 2 3 if(((p->rear+1) % MAXSIZE) == (p->front % MAXSIZE)) 4 return 1; 5 6 return 0; 7 8 } 9 10 int SequenQueue_Empty(SequenQueue *p){ 11 if(p->front == p->rear) 12 return 1; 13 14 return 0; 15 }
入队和出队
1 int Delete_SequenQueue(SequenQueue *p){ 2 3 if(SequenQueue_Empty(p)) 4 return 0; 5 6 p->front = (p->front+1) % MAXSIZE; 7 return 1; 8 9 } 10 11 int Enter_SequenQueue(SequenQueue *p,elemtype e){ 12 13 if(SequenQueue_Full(p)) 14 return 0; 15 16 p->date[p->rear] = e; 17 p->rear = (p->rear+1) % MAXSIZE; 18 return 1; 19 20 }