c语言版动态数组循环队列

来源:互联网 发布:盲僧龙年限定皮肤淘宝 编辑:程序博客网 时间:2024/05/04 17:52

#include <iostream>
#include <assert.h>
using namespace std;
/*
struct Node
{
 int info;
 Node *next;
};

struct queuelk
{
 struct Node *front;
 struct Node *back;
};


void init_queue(struct queuelk* q)
{
 q->back = q->front = NULL;
}

void queue_is_empty(struct queuelk *q)
{
 if(q->front==NULL)
 {
  return;
 }
}

void enqueue(struct queuelk *q, int info)
{
 struct Node *temp = NULL;
 temp = (Node*)malloc(sizeof(Node));
 assert(temp!=NULL);
 if(q->front == NULL)     //这是队列的第一个结点
 {
  q->front = q->back = temp;
  temp->info = info;
  return;
 }
 q->back->next = temp;
 temp->info = info;
 q->back = temp;
}

bool dequeue(struct queuelk *q, int *info)
{
 if(q->front == NULL)
 {
  return false;
 }
 *info = q->front->info;
 if(q->front == q->back)
 {
  free(q->front);
  q->front = q->back = NULL;
  return true;
 }
 q->front = q->front->next;
 return true;
}
*/

//这是个通用队列.

//写一个循环队列.
//

 

struct queuelk
{
 int *arr;
 int rear;
 int size;
 int front;
};


void init_queue(struct queuelk *q, int size)
{
 q->front = -1;     //这个-1很重要
 q->rear = -1;
 if(size<=0)
 {
  printf("队列长度为负,请注意/n");
  exit(1);
 }
 q->size = size;
 q->arr = (int*)malloc(sizeof(int)*size);
 if(q->arr == NULL)
 {
  printf("空间申请失败");
  exit(1);
 }
}

void againMalloc(struct queuelk *q, int newsize)
{
  int *pnew = (int*)malloc(sizeof(int)*newsize);
  int *pold = q->arr;
  int i=0;
  int limit =0;
  //memcpy(pnew, q->arr, q->size);       //直接调用memcpy()不是更方便吗?
     limit = (newsize > q->size) ? q->size : newsize;
     for(; i<limit; i++)
  {
   pnew[i] = q->arr[i];
  }
  free(q->arr);
  q->arr = pnew;
  q->size = newsize;
}

 

void enqueue(struct queuelk *q, int info)
{  
 if(q->front == 0 && q->rear+1 == q->size || q->rear+1 == q->rear)
 {
  againMalloc(q, q->size<<1);       //空间成倍增长
  if((q->rear) < q->front)
  {
   int i= q->size>>1 -1;       //原队列大小
   int j  = q->size-1;        //现在是新空间的大小了.
   for(; i>= q->front; i--)
   {
    q->arr[j] = q->arr[i];
    j--;
   }
   q->front = ++j;         //最后那个位置j多一定多前进了一个位置,所以++1;
  }
 }
 q->rear = (q->rear==q->size)? 0 : ++q->rear;
 if(q->front == -1)          //第一个元素.
 { 
   q->front = 0;          //追上了才算是队列满.
 }
 q->arr[q->rear] = info;         //每次在队尾入队,分析一下用什么条件判断队满..什么条件呢
}


bool dequeue(struct queuelk *q, int *info)
{
  int newsize = 0;          //需要计算一下新的队列中元素个数.
  int trysize = q->size;
  if(q->front == -1)          //先判断一下是否队空
  {
   return false;
  }
  *info = q->arr[q->front];
  if(q->front == q->rear)        //判断出队的是不是最后一个元素
  {
   q->front = q->rear =-1;       //结束标记在哪种数据结构里都很重要..
  }
  else
  {
   q->front = (q->front== q->size) ? 0 : ++q->front; 
  }
  newsize = (q->front<=q->rear)?q->rear-q->front+1:q->rear+q->size-q->front+1;
  while(newsize<=trysize>>2 && trysize>2)    //真麻烦.
  {
    trysize >>= 1;          //容量减半
  }

  if(trysize < q->size)         //如果数组容量发生了变化这时再移动里面的元素,然后再将容量减半.
  {
  if(q->rear>=trysize && q->front <= q->rear)   //如果尾部索引>=新生成的空间,开始移到数组的元素,数组索引都是从0开始,索引越在前越小.
  {
   int i = q->front;
   int j =0;
   for(; i<=q->rear; i++)
   {
    q->arr[j] = q->arr[i];
    j++;
   }
   q->front = 0;
   q->rear = --j;        //生成新的队头和队尾指针.
  }
  else if(q->front>q->rear)
  {
    int i = q->size-1;
    int j= trysize-1;
    for(; i>=q->front; i--)
    {
     q->arr[j] = q->arr[i];
     j--;
    }
    q->front = ++j;
  }
  againMalloc(q, trysize);
  }
  return true;
}

int main()
{
 struct queuelk queue;
 init_queue(&queue,2);
 for(int i=0; i<5000; i++)
 {
  enqueue(&queue, i);
 }
 int ou= 0;

 while(dequeue(&queue, &ou))
 {
  cout<<ou<<endl;
 }
 
 return 0;
}

原创粉丝点击