队列(FIFO: first in first out)
特征:先进先出
基本操作:入队:push
出队:pop
分类:用数组完成->数组队列
用链表完成->链表对列
链表:队头指针(数组:队头下标):front:Pop
链表:队尾指针(数组:队尾下标):rear:Push
循环队列:循环的出现是为了解决数组队列空间无法循环使用的问题
判断循环队列满的条件:(rear+1)%10=front
1、搭建所需使用的库:(双向链表库)
struct Node
{
ElementType data; //存储值
struct Node* next; //存储下一下节点的地址
struct Node* prev; //存储上一个节点的地址
}; //有两个指针,这啥双向链表的特点
struct DLinkList
{
struct Node *head; //存储队头位置
struct Node *tail; //存储队尾位置
int len; //存储链表长度
}; //同时存储队尾队头位置,就可以从两个方向查找
int InitDLinkList(DLlist *list) //初始化链表
{
list->len=0;
list->head=NULL;
list->tail=NULL; //链表长度为零,队头队尾指向空
return true;
}
struct Node* CreateNode(ElementType element) //创建链表空节点
{
struct Node* NewNode=(struct Node*)malloc(sizeof(struct Node));//申请空间在NewNode这个结构体中
if(NewNode==NULL)
{
printf("CreateNode malloc error");
return NULL; //如果未申请成功,即newNode为空则返回NULL
}
NewNode->data=element;
NewNode->next=NULL;
NewNode->prev=NULL;
return NewNode; //结果不为空则将值存在data,并将返回NewNode这个结构体指针
}
void InsertTail(DLlist *list, ElementType element) //尾插法
{
struct Node*newNode=CreateNode(element);
if(newNode==NULL)
{
printf("inserttail CreateNode error!\n");
return ;
} //判断是否为空
if(list->len==0)
{
list->head=newNode;
list->tail=newNode;//如果链表长度为0,则队头队尾指针都指向newNode
}
else
{
list->tail->next=newNode; //将队尾的下一个指向newNode
newNode->prev=list->tail; //将newNode指向队尾
list->tail=newNode; //将newNode赋值给队尾
}
list->len++;
}
void Travel(DLlist *list) //遍历打印
{
printf("next: ");
struct Node*TravelPoint=list->head; //创建一个遍历的指针,先进行头遍历
while(TravelPoint!=NULL)
{
printf("%d ",TravelPoint->data);
TravelPoint=TravelPoint->next; //判断是否遍历结束,未结束就打印值并到下一位
}
printf("\n");
printf("prev: ");
TravelPoint=list->tail; //再进行尾遍历
while(TravelPoint!=NULL)
{
printf("%d ",TravelPoint->data);
TravelPoint=TravelPoint->prev; //判断是否遍历结束,未结束就打印值并到上一位
}
printf("\n");
}
int FindFirstByElement(DLlist *list, ElementType element) //查找第一个与值相同的数并返回位置
{ int count=-1;
struct Node *TravelPoint=list->head;
while(TravelPoint!=NULL)
{
if(TravelPoint->data==element)
return count+1;
count++;
TravelPoint=TravelPoint->next;
}
return -1;
}
void RemoveByElement(DLlist *list, ElementType element)
{ //将所有返回回来位置的值删除
int count=FindFirstByElement(list,element);
while(count!=-1)
{
RemoveByIndex(list,count);
count=FindFirstByElement(list,element);
}
}
void RemoveByIndex(DLlist *list, int index)
{ //删除index位置的值
if(index<0||index>=list->len)
{
printf("RemoveByIndex invaild error! \n");
return ;
}
if(index==0)
{//单独判断当删除位置在首位时的情况
if(list->len==1)
{
free(list->head);
list->head=NULL;
list->tail=NULL;
list->len--;
return;
}
struct Node *temp=list->head;
list->head=list->head->next;
list->head->prev=NULL;
free(temp);
list->len--;
return ;
}
if(index==list->len-1)
{ //单独判断当删除位置在末尾的情况
struct Node *temp=list->tail;
list->tail=list->tail->prev;
list->tail->next=NULL;
free(temp);
list->len--;
return ;
}
struct Node *TravelPoint=list->head;
while(index!=0)
{
TravelPoint=TravelPoint->next;
index--;
} //正常情况下的循环遍历
TravelPoint->prev->next=TravelPoint->next;
TravelPoint->next->prev=TravelPoint->prev;
free(TravelPoint);
list->len--;
}
void InsertHead(DLlist *list, ElementType element)
{ //头插法
struct Node*newNode=CreateNode(element);
if(newNode==NULL)
{
printf("inserttail CreateNode error!\n");
return ;
}
if(list->len=0)
{
list->head=newNode;
list->tail=newNode;
}
else
{
list->head->prev=newNode;
newNode->next=list->head;
list->head=newNode;
}
}
void FreeDLinkList(DLlist *list) //释放堆上空间的函数
{
while(list->head!=NULL)
{
struct Node*temp=list->head->next;
free(list->head);
list->head=temp;
}
list->len=0;
list->head=NULL;
list->tail=NULL;
}
2、链表队列
struct LinkQueue
{
DLlist queue;
ElementType FrontData;
};
int InitLQueue(LQueue *lq)
{
return InitDLinkList(&lq->queue);
}
void QPush(LQueue *lq, ElementType element)
{
InsertTail(&lq->queue,element);
}
ElementType *QPop(LQueue *lq)
{
if(lq->queue.len==0)
{
printf("the queue is empty!\n");
return NULL;
}
lq->FrontData=lq->queue.head->data;
RemoveByIndex(&lq->queue,0);
return &lq->FrontData;
}
int IsQEmpty(LQueue *lq)
{
if(lq->queue.len==0)
{
return true;
}
else
{
return false;
}
}
struct Node *GetFront(LQueue *lq)
{
return lq->queue.head;
}
void FreeLQueue(LQueue *lq)
{
FreeDLinkList(&lq->queue);
}
3、链式栈
struct LinkStack
{
DLlist stack;
ElementType Topdata;
};
int InitLinkStack(LStack *s)
{
return InitDLinkList(&s->stack);
}
struct Node *GetTop(LStack *s)
{
return s->stack.tail;
}
void Push(LStack *s,ElementType element)
{
InsertTail(&s->stack,element);
}
ElementType* Pop(LStack *s)
{
if(s->stack.tail==NULL)
{
return NULL;
}
s->Topdata=s->stack.tail->data;
RemoveByIndex(&s->stack,s->stack.len-1);
return &s->Topdata;
}
int IsEmpty(LStack *s)
{
if(s->stack.len==0)
{
return true;
}
else
{
return false;
}
}
void FreeStack(LStack *s)
{
FreeDLinkList(&s->stack);
}
- 两个栈实现一个队列
struct Queue
{
LStack stack1;
LStack stack2; //定义两个队列
};
void InitQueue(struct Queue *qp)
{
InitLinkStack(&qp->stack1);
InitLinkStack(&qp->stack2);
}
int StackQueueIsEmpty(struct Queue *qp)
{
if(qp->stack1.stack.len==0&&qp->stack2.stack.len==0)
{
return true;
}
else
{
return false;
}
}
void StackQueuePush(struct Queue *qp,ElementType element)
{ //现将数据压入第一个栈中,再将数据先进后出压入第二个栈,实现队列的先进先出
while(IsEmpty(&qp->stack2)==false)
{//如果第二个栈里面还有值,就先压回第一个栈
Push(&qp->stack1,*Pop(&qp->stack2));
}
Push(&qp->stack1,element);
}
ElementType* StackQueuePop(struct Queue *qp)
{
while(IsEmpty(&qp->stack2)==true)
{//当第二个栈为空,第一个栈有值时,将第一个栈的值全部压入第二个栈
while(IsEmpty(&qp->stack1)==false)
{
Push(&qp->stack2,*Pop(&qp->stack1));
}
}
return Pop(&qp->stack2);
}
int main()
{
struct Queue queue;
InitQueue(&queue);
for(int i=0;i<10;i++)
{
StackQueuePush(&queue,i+1);
}
while(StackQueueIsEmpty(&queue)==false)
{
printf("%d ",*StackQueuePop(&queue));
}
printf("\n");
return 0;
}
- 两个队列实现一个栈
struct QueueStack
{
LQueue queue1;
LQueue queue2; //定义两个队列
};
int InitQueueStack(struct QueueStack *s)
{//初始化队列
InitLQueue(&s->queue1);
InitLQueue(&s->queue2);
return true;
}
void QueueStackPush(struct QueueStack *s,ElementType element)
{//哪一个队列里没有数就将值压入另一个队列
if(s->queue1.queue.len==0)
{
QPush(&s->queue2,element);
}
else
{
QPush(&s->queue1,element);
}
}
int IsQueueStackEmpty(struct QueueStack *s)
{
if(s->queue1.queue.len==0&&s->queue2.queue.len==0)
{
return true;
}
else
{
return false;
}
}
ElementType *QueueStackPop(struct QueueStack *s)
{
if(IsQueueStackEmpty(s)==true)
{
printf("stack is empty!");
return NULL;
}
if(s->queue1.queue.len==0)
{//哪个队列的数为零,就将另一个队列里的值留下最后一位,其余全压入数为零的队列中,再返回那个最后的值,以此来实现栈的先进后出
while(s->queue2.queue.len>1)
{
QPush(&s->queue1,*QPop(&s->queue2));
}
return QPop(&s->queue2);
}
else
{
while(s->queue1.queue.len>1)
{
QPush(&s->queue2,*QPop(&s->queue1));
}
return QPop(&s->queue1);
}
}
int main()
{
struct QueueStack s;
InitQueueStack(&s);
for(int i=0;i<10;i++)
{
QueueStackPush(&s,i+1);
}
while(IsQueueStackEmpty(&s)==false)
{
printf("%d ",*QueueStackPop(&s));
}
printf("\n");
return 0;
}