C语言第七课(队列)

   队列(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);

}

  1. 两个栈实现一个队列

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;

}

  1. 两个队列实现一个栈

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;

}

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值