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

#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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 请编写一个函数,将一个数组转化成链表,并返回链表的头指针。 ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *next; } Node; Node* array_to_linkedlist(int arr[], int size) { Node *head = NULL, *tail = NULL; for (int i = 0; i < size; i++) { Node *node = (Node*)malloc(sizeof(Node)); node->data = arr[i]; node->next = NULL; if (head == NULL) { head = tail = node; } else { tail->next = node; tail = node; } } return head; } int main() { int arr[] = {1, 2, 3, 4, 5}; int size = sizeof(arr) / sizeof(arr[0]); Node *head = array_to_linkedlist(arr, size); // 遍历链表 Node *p = head; while (p != NULL) { printf("%d ", p->data); p = p->next; } return 0; } ``` 2. 请编写一个函数,判断一个链表是否是循环链表,如果是循环链表,返回 1,否则返回 0。 ```c #include <stdio.h> #include <stdlib.h> typedef struct Node { int data; struct Node *next; } Node; int is_circular_linkedlist(Node *head) { if (head == NULL) { return 0; } Node *p = head, *q = head; while (q != NULL && q->next != NULL) { p = p->next; q = q->next->next; if (p == q) { return 1; } } return 0; } int main() { Node *head = (Node*)malloc(sizeof(Node)); head->data = 1; Node *p1 = (Node*)malloc(sizeof(Node)); p1->data = 2; head->next = p1; Node *p2 = (Node*)malloc(sizeof(Node)); p2->data = 3; p1->next = p2; Node *p3 = (Node*)malloc(sizeof(Node)); p3->data = 4; p2->next = p3; // 将链表变成循环链表 p3->next = head; printf("%d\n", is_circular_linkedlist(head)); return 0; } ``` 3. 请编写一个函数,实现队列的入队和出队操作。 ```c #include <stdio.h> #include <stdlib.h> #define MAX_SIZE 100 typedef struct Queue { int data[MAX_SIZE]; int front, rear; } Queue; Queue* create_queue() { Queue *q = (Queue*)malloc(sizeof(Queue)); q->front = q->rear = 0; return q; } int is_full(Queue *q) { return (q->rear + 1) % MAX_SIZE == q->front; } int is_empty(Queue *q) { return q->front == q->rear; } void enqueue(Queue *q, int x) { if (is_full(q)) { printf("Queue is full.\n"); return; } q->data[q->rear] = x; q->rear = (q->rear + 1) % MAX_SIZE; } int dequeue(Queue *q) { if (is_empty(q)) { printf("Queue is empty.\n"); return -1; } int x = q->data[q->front]; q->front = (q->front + 1) % MAX_SIZE; return x; } int main() { Queue *q = create_queue(); enqueue(q, 1); enqueue(q, 2); enqueue(q, 3); printf("%d\n", dequeue(q)); printf("%d\n", dequeue(q)); printf("%d\n", dequeue(q)); printf("%d\n", dequeue(q)); return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值