1.队列
队列:
队列是只允许在一段进行插入,而在另一端进行删除操作的线性表。
允许插入的称谓队尾,允许删除的一端队头。
顺序队列。
循环队列,
常用操作,入队,出队。
先进先出,FIFO
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
typedef int DATATYPE;
typedef struct queue {
DATATYPE *pty;
int tlen;
int head;
int tail;
}SeqQueue;
int DestroySeqQueue(SeqQueue *queue);
DATATYPE QuitSeqQueue(SeqQueue *queue);
int EnterSeqQueue(SeqQueue *queue, DATATYPE data);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
SeqQueue *CreateSeqQueue(int len);
#endif
实例 1
主函数
#include <stdio.h>
#include "seqqueue.h"
int main()
{
SeqQueue* sq = CreateSeqQueue(10);
int i = 0 ;
for(i = 0 ;i<10;i++)
{
EnterSeqQueue(sq,&i);
}
for(i = 0 ;i<10;i++)
{
DATATYPE* tmp = GetHeadSeqQueue(sq);
if(NULL == tmp)
{
break;
}
printf("%d\n",*tmp);
QuitSeqQueue(sq);
}
DestroySeqQueue(sq);
printf("Hello World!\n");
return 0;
}
.h文件
#ifndef SEQQUEUE_H
#define SEQQUEUE_H
typedef int DATATYPE;
typedef struct queue {
DATATYPE *array;
int tlen;
int head;
int tail;
}SeqQueue;
int DestroySeqQueue(SeqQueue *queue);
DATATYPE QuitSeqQueue(SeqQueue *queue);
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data);
int IsEmptySeqQueue(SeqQueue *queue);
int IsFullSeqQueue(SeqQueue *queue);
SeqQueue *CreateSeqQueue(int len);
#endif // SEQQUEUE_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include "seqqueue.h"
SeqQueue *CreateSeqQueue(int len)
{
SeqQueue * sq = malloc(sizeof(SeqQueue));
if(NULL == sq)
{
perror("CreateSeqQueue");
return NULL;
}
sq->array = malloc(sizeof(DATATYPE)*len);
if(NULL == sq->array)
{
perror("CreateSeqQueue");
return NULL;
}
sq->head = 0;
sq->tail = 0 ;
sq->tlen = len;
return sq;
}
int EnterSeqQueue(SeqQueue *queue, DATATYPE *data)
{
if(IsFullSeqQueue(queue))
{
fprintf(stderr,"EnterSeqQueue error\n");
return 1;
}
memcpy(&queue->array[queue->tail],data,sizeof(DATATYPE));
queue->tail = (queue->tail+1)%queue->tlen;
return 0;
}
int IsEmptySeqQueue(SeqQueue *queue)
{
return queue->head == queue->tail;
}
int IsFullSeqQueue(SeqQueue *queue)
{
return queue->head == (queue->tail+1) %queue->tlen;
}
int QuitSeqQueue(SeqQueue *queue)
{
if(IsEmptySeqQueue(queue))
{
fprintf(stderr,"QuitSeqQueue error\n");
return 1;
}
queue->head= (queue->head +1)%queue->tlen;
return 0;
}
DATATYPE *GetHeadSeqQueue(SeqQueue *queue)
{
if(IsEmptySeqQueue(queue))
{
return NULL;
}
return &queue->array[queue->head];
}
int DestroySeqQueue(SeqQueue *queue)
{
free(queue->array);
free(queue);
return 0;
}
2.链式队列
链式队列是一种使用链表来实现的队列结构。队列是一种先进先出(FIFO,First In First Out)的数据结构,它允许在一端进行插入操作,而在另一端进行删除操作。在链式队列中,插入操作通常在队尾进行,而删除操作在队头进行。
链式队列的基本结构包括:
- 队头指针:指向队列的第一个元素(即最早插入的元素)。
- 队尾指针:指向队列的最后一个元素(即最近插入的元素)。
- 链表节点:每个节点包含存储的数据和指向下一个节点的指针。
链式队列的主要操作包括:
- 入队(Enqueue):在队列的尾部插入一个新的元素。这通常涉及创建一个新的节点,将其数据字段设置为要插入的值,并将其指针字段设置为null(因为它将成为新的队尾),然后更新队尾指针以指向这个新节点。
- 出队(Dequeue):删除队列头部的元素。这通常涉及将队头指针更新为指向队列的第二个元素(即删除第一个元素)。
- 查看队头元素(Peek/Front):返回队列头部的元素,但不删除它。
- 检查队列是否为空:如果队头指针和队尾指针都为null,则队列为空。
链式队列的一个主要优点是它不需要像数组队列那样进行元素的移动。当数组队列进行出队操作时,可能需要将所有后续元素向前移动一位以填补空缺,这在大数据集上可能是一个昂贵的操作。链式队列通过指针直接链接元素,避免了这种开销。
#ifndef __HEAD_H__
#define __HEAD_H__
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <error.h>
#include <errno.h>
#define error_exit(_errmsg_) error(EXIT_FAILURE, errno, _errmsg_)
typedef int DATATYPE;
typedef struct node {
DATATYPE data;
struct node *next;
}QueueNode;
typedef struct queue {
QueueNode *head;
int tlen;
int clen;
QueueNode *tail;
}LinkQueue;
int DestroyLinkQueue(LinkQueue *queue);
DATATYPE QuitLinkQueue(LinkQueue *queue);
int EnterLinkQueue(LinkQueue *queue, DATATYPE data);
int IsFullLinkQueue(LinkQueue *queue);
int IsEmptyLinkQueue(LinkQueue *queue);
LinkQueue *CreateLinkQueue(int len);
DATATYPE *GetHeadLinkQueue(LinkQueue *queue);
#endif
实例 2
LinkQueue *CreateLinkQueue() { LinkQueue* lq =(LinkQueue*)malloc(sizeof(LinkQueue)); if(NULL == lq) { perror("CreateLinkQueue malloc"); return NULL; } lq->head =NULL; lq->tail =NULL; lq->clen = 0 ; return lq; }
int EnterLinkQueue(LinkQueue *queue, DATATYPE *data) { QueueNode*newnode = (QueueNode*)malloc(sizeof(QueueNode)); if(NULL == newnode) { perror("EnterLinkQueue malloc"); return 1; } memcpy(&newnode->data,data,sizeof(DATATYPE)); newnode->next = NULL; if(IsEmptyLinkQueue(queue)) { queue->head = newnode; queue->tail = newnode; } else { queue->tail->next = newnode; queue->tail = newnode; } queue->clen++; return 0; }
int IsEmptyLinkQueue(LinkQueue *queue) { return 0 == queue->clen; }
int QuitLinkQueue(LinkQueue *queue) { if(IsEmptyLinkQueue(queue)) { return 1; } QueueNode* tmp = queue->head; queue->head = queue->head->next; if(NULL ==queue->head) { queue->tail = NULL; } free(tmp); queue->clen--; return 0; }
DATATYPE *GetHeadLinkQueue(LinkQueue *queue) { if(IsEmptyLinkQueue(queue)) { return NULL; } return &queue->head->data; }
int GetSizeLinkQueue(LinkQueue *queue) { return queue->clen; }
int DestroyLinkQueue(LinkQueue *queue) { int i =0 ; int len = GetSizeLinkQueue(queue); for(i=0;i<len;i++) { QuitLinkQueue(queue); } free(queue); return 0; }
.h
#ifndef LINKQUEUE_H #define LINKQUEUE_H #ifndef __HEAD_H__ #define __HEAD_H__ typedef int DATATYPE; typedef struct node { DATATYPE data; struct node *next; }QueueNode; typedef struct queue { QueueNode *head; int clen; QueueNode *tail; }LinkQueue; LinkQueue *CreateLinkQueue(); int EnterLinkQueue(LinkQueue *queue, DATATYPE *data); int QuitLinkQueue(LinkQueue *queue); int IsEmptyLinkQueue(LinkQueue *queue); int DestroyLinkQueue(LinkQueue *queue); DATATYPE * GetHeadLinkQueue(LinkQueue *queue); int GetSizeLinkQueue(LinkQueue *queue); #endif #endif // LINKQUEUE_H
main.c
#include <stdio.h> #include "linkqueue.h" int main() { LinkQueue* lq = CreateLinkQueue(); int i = 0 ; for(i=0;i<10;i++) { EnterLinkQueue(lq,&i); } int size = GetSizeLinkQueue(lq); for(i=0;i<size;i++) { DATATYPE* tmp = GetHeadLinkQueue(lq); printf("%d\n",*tmp); QuitLinkQueue(lq); } DestroyLinkQueue(lq); return 0; }