存储结构: 对数据 以及 数据关系的 存储
连续存储: 将所有数据放到一起 数组
离散存储: 数据可能分布在内存的 不同位置
对数的操作(算法):
不是简单的数值操作 而是一些 逻辑操作
增: 增加数据
删: 删除数据
改: 修改数据
查: 查找或遍历数据
一.构造顺序队列
1.定义结构 定义队列 创建空队列
#include <stdio.h>
#include <stdlib.h>
//定义结构
typedef int Data_t;
//定义循环队列
typedef struct queue_t
{
Data_t *data; // 数组容器 堆区分配
int max_len; // 容器大小
int push_i; // 入口下标
int pull_i; // 出口下标
}queue_t;
//创建空队列 初始化队列
int init_queue(queue_t *head, int size)
{
if(head == NULL || size == 0) return -1;
size += 1; // 实际存储空间 比真实需要的空间大一个
head->data = (Data_t *)malloc(size * sizeof(Data_t));
if(head->data == NULL) return -2;
head->max_len = size;
head->push_i = 0;
head->pull_i = 0;
return 0;
}
2.数据入队列 数据出队列
//入队
int queue_push(queue_t *head, Data_t data)
{
if(head == NULL) return -1;
//判断满否
if( (head->push_i + 1 ) % head->max_len == head->pull_i )
{
printf("队列满了!\n");
return -2;
}
//数据入队 先存后移动
head->data[ head->push_i ] = data;
head->push_i =( head->push_i + 1) % head->max_len;
return 0;
}
//数据出队列
int queue_pull(queue_t *head, Data_t *data)
{
if(head == NULL || data == NULL) return -1;
//判断空否
if( head->push_i == head->pull_i )
{
printf("队列空!\n");
return -2;
}
*data = head->data[head->pull_i];
head->pull_i = (head->pull_i + 1) % head->max_len;
return 0;
}
3.置空队列
//置空队列
int set_empty(queue_t *head)
{
if(head == NULL) return -1;
head->push_i = 0;
head->pull_i = 0;
return 0;
}
4.销毁队列
//销毁队列
int del_queue(queue_t *head)
{
if(head == NULL) return -1;
free(head->data);
head->max_len = 0;
head->push_i = 0;
head->pull_i = 0;
return 0;
}
5.获取队列中有多少数据
//获取队列中 现在有多少个数据
int get_len(queue_t *head)
{
if(head==NULL) return -1;
int len = 0;
if(head->push_i < head->pull_i) len = head->push_i + head->max_len - head->pull_i;
else len = head->push_i - head->pull_i;
return len;
}
6.演示各个函数
int main()
{
queue_t q1;
init_queue(&q1, 5);
for(int i=0;i< 7;i++)
{
printf("%d 入队!\n",i);
queue_push(&q1, i);
}
Data_t data;
for(int i=0;i<3; i++)
{
if( queue_pull(&q1, &data) == 0 )
printf("%d ",data);
}
for(int i=0;i< 3;i++)
{
printf("%d 入队!\n",i);
queue_push(&q1, i);
}
//全部出完
while( queue_pull(&q1, &data) == 0)
{
printf("%d ",data);
int len = get_len(&q1);
printf("q1中还有%d个元素\n", len);
}
return 0;
}
7.演示结果
8.顺序队列逻辑分析图
二.构造双向循环队列
1.构造循环队列的主体函数
#include <stdio.h>
#include <stdlib.h>
//双向循环链表队列
//定义类型
typedef int Data_t;
//定义节点
typedef struct node_t
{
Data_t data;
struct node_t *prov; //前项指针
struct node_t *next; //后项指针
}node_t;
//创建空队列
node_t *create_link_queue(void)
{
node_t *p = (node_t *)malloc(sizeof(node_t));
if(p)
{//头尾循环
p->prov = p;
p->next = p;
}
return p;
}
//数据入队 头部插入法
int push_link_queue(node_t *head, Data_t data)
{
if(head == NULL) return -1;
node_t *p = (node_t *)malloc(sizeof(node_t));
if(p == NULL) return -2;
p->data = data;
p->next = head->next;
p->prov = head;
p->next->prov = p;
head->next = p;
return 0;
}
//数据出队 尾部删除
int pull_link_queue(node_t *head, Data_t *data)
{
if(head == NULL || data == NULL) return -1;
//判空
if(head->next == head) return -2;
node_t *p = head->prov; // p指向尾部要删除的节点
head->prov = p->prov;
p->prov->next = head;
*data = p->data;
free(p);
return 0;
}
//销毁队列
int del_link_queue(node_t *head)
{
if(head == NULL) return -1;
node_t *p;//临时节点指针p
while(head->next != head)
{
p=head->next;//从头部删除
head->next = p->next;
free(p);
}
free(head);//最后删除头
return 0;
}
//得到队列的长度
int get_queue_len(node_t *head)
{
if(head == NULL ) return -1;
int len = 0;
node_t *p = head;
for(; p->next != head ;p=p->next, len++);
return len;
}
2.演示各个函数
int main()
{
node_t *Q;
Q=create_link_queue();
for(int i=0;i<10;i++) push_link_queue(Q, i);
printf("队列创建完成,有%d个数据!\n",get_queue_len(Q));
Data_t data;
while( pull_link_queue(Q, &data) == 0 )
{
printf("数据%d 出队,还剩余%d个!\n",data,get_queue_len(Q) );
}
//删除队列
del_link_queue(Q);
return 0;
}
3.演示结果
4.循环队列逻辑分析图