数据结构基本概念
数据结构:
是相互之间存在一种或多种特定关系的数据元素的集合
数据结构的三个层次:
抽象层-逻辑结构、结构层-物理结构、实现层-运算结构
数据结构三要素:
逻辑结构、物理结构、运算结构
- 逻辑结构:分为线性结构和非线性结构
(1) 集合:数据元素之间同属于一个集合,无其他关系只堆积在一起,属于非线性结构
(2) 线性表:数据元素之间存在一对一的关系,属于线性结构
(3) 树形结构:数据元素之间存在一对多的关系,属于非线性结构
(4) 图/网状结构:数据元素之间存在多对多的关系,属于非线性结构
- 物理结构:也称存储结构,分为顺序存储、链式存储、索引存储、散列存储
(1) 顺序结构:使用连续的内存地址,数据元素由存储单元邻接关系来体现(数组描述),随机存取访好、空间利用程度不好、插删差;顺序表(数组)、顺树
(2) 链式结构:用不连续的内存地址(也可连续),数据元素是节点组成,节点由数据和地址组成,随机存取访不好、空间利用程度充分、插删好;链式表(链表)、链树
- 运算结构:在数据上运算包括定义与实现
(1)定义:针对逻辑结构的,指出运算的功能
(2)实现:针对物理结构的,指出运算具体操作步骤,如创建销毁、插入删除、取出修改、排序查找
数据结构中的队列(queue)
- 队列:简称队,也是一种操作受限的线性表。只允许在表的一端进行插入,而在表的另一端进行删除。
- 特点:先进先出(FIFO),如:进1.2.3.4.5,出1.2.3.4.5;想象比如排队,在学校里每次星二晚上上完课,都会去饭堂排队买番薯吃,谁先排的队,谁就先买。先进先出(FIFO)
- 队头:又称队首,允许删除的一端
- 队尾:允许插入的一端
- 空队:不含任何元素的空表
队列的顺序存储结构,(循环队列)的实现
顺序结构就是循环队列
定义声明函数:
/**
*C实现:定义声明函数
*/
#ifndef SEQUENCE_H_INCLUDED
#define SEQUENCE_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
typedef struct Queue_sx{
int* arr; //数组首地址
size_t cap; //容量
size_t front; //队首
size_t rear; //队尾
size_t size; //数量
}QUEUE_SX;
//初始化队列
void queue_sx_init(QUEUE_SX* queue, size_t cap);
//释放化队列
void queue_sx_deinit(QUEUE_SX* queue);
//判断队列空
int queue_sx_empty(QUEUE_SX* queue);
//判断队列满
int queue_sx_full(QUEUE_SX* queue);
//入队
void queue_sx_push(QUEUE_SX* queue, int data);
//出队
int queue_sx_pop(QUEUE_SX* queue);
//查看队首
int queue_sx_front(QUEUE_SX* queue);
//元素数量
size_t queue_sx_size(QUEUE_SX* queue);
#endif // SEQUENCE_H_INCLUDED
声明函数实现:
/**
*C实现:声明函数实现
*/
#include "sequence.h"
//初始化队列
void queue_sx_init(QUEUE_SX* queue, size_t cap)
{
queue->arr = malloc(cap * sizeof(int));
queue->cap = cap;
queue->front = 0;
queue->rear = 0;
queue->size = 0;
}
//释放化队列
void queue_sx_deinit(QUEUE_SX* queue)
{
free(queue->arr);
queue->arr = NULL;
queue->cap = 0;
queue->front = 0;
queue->rear = 0;
queue->size = 0;
}
//判断队列空
int queue_sx_empty(QUEUE_SX* queue)
{
return !queue->size;
}
//判断队列满
int queue_sx_full(QUEUE_SX* queue)
{
return queue->size >= queue->cap;
}
//入队
void queue_sx_push(QUEUE_SX* queue, int data)
{
if(queue->rear >= queue->cap){
queue->rear = 0;
}queue->size += 1;
queue->arr[queue->rear++] = data;
}
//出队
int queue_sx_pop(QUEUE_SX* queue)
{
if(queue->front >= queue->cap){
queue->front = 0;
}queue->size -= 1;
return queue->arr[queue->front++];
}
//查看队首
int queue_sx_front(QUEUE_SX* queue)
{
if(queue->front >= queue->cap){
queue->front = 0;
}return queue->arr[queue->front];
}
//元素数量
size_t queue_sx_size(QUEUE_SX* queue)
{
return queue->size;
}
实现函数验证:
/**
*C实现:实现函数验证
*/
#include "sequence.h"
int main()
{
int i;
QUEUE_SX queue_sx;
queue_sx_init(&queue_sx, 5);//初始
for(i = 0; !queue_sx_full(&queue_sx); i++){//判断满后退出
queue_sx_push(&queue_sx, i+1);//入队
}
printf("队首=%d\n", queue_sx_front(&queue_sx));//队首
printf("数量=%d\n", queue_sx_size(&queue_sx));//数量
while(!queue_sx_empty(&queue_sx)){//判断空后,不再出队
printf("%d\n", queue_sx_pop(&queue_sx));//出队
}
queue_sx_deinit(&queue_sx);//释放
return 0;
}
结果:
队列的链式存储结构,链式表的实现
跟单向链表相似
定义声明函数:
/**
*C实现:定义声明函数
*/
#ifndef CHAIN_H_INCLUDED
#define CHAIN_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
typedef struct QueueNode{ //节点结构
int data; //数据
struct QueueNode* next; //指向下一个节点地址
}QUEUE_NODE;
typedef struct Queue_ls{ //队结构
QUEUE_NODE* front; //队首节点指针
QUEUE_NODE* rear; //队尾节点指针
}QUEUE_LS;
//初始化队列
void queue_ls_init(QUEUE_LS* queue);
//释放化队列
void queue_ls_deinit(QUEUE_LS* queue);
//判断队列空
int queue_ls_empty(QUEUE_LS* queue);
//入队
void queue_ls_push(QUEUE_LS* queue, int data);
//出队
int queue_ls_pop(QUEUE_LS* queue);
//查看队首
int queue_ls_front(QUEUE_LS* queue);
//元素数量
size_t queue_ls_size(QUEUE_LS* queue);
#endif //CHAIN_H_INCLUDED
声明函数实现:
/**
*C实现:声明函数实现
*/
#include "chain.h"
//创建节点(创建一个)
static QUEUE_NODE* create_queue_node(int data)
{
QUEUE_NODE* node = malloc(sizeof(QUEUE_NODE));
node->data = data;
node->next = NULL;
return node;
}
//销毁节点(销毁一个)
static QUEUE_NODE* destroy_queue_node(QUEUE_NODE* node)
{
QUEUE_NODE* next = node->next;
free(node);
return next;
}
//初始化队列
void queue_ls_init(QUEUE_LS* queue)
{
queue->front = NULL;
queue->rear = NULL;
}
//释放化队列(释放空间)
void queue_ls_deinit(QUEUE_LS* queue)
{
while(queue->front){
queue->front = destroy_queue_node(queue->front);
}queue->rear = NULL;
}
//判断队列空(没满)
int queue_ls_empty(QUEUE_LS* queue)
{
return !queue->front && !queue->rear;
}
//入队
void queue_ls_push(QUEUE_LS* queue, int data)
{
QUEUE_NODE* rear = create_queue_node(data);
if(queue->rear){
queue->rear->next = rear;
}else queue->front = rear;
queue->rear = rear;
}
//出队
int queue_ls_pop(QUEUE_LS* queue)
{
int data = queue->front->data;
if(!(queue->front = destroy_queue_node(queue->front))){
queue->rear = NULL;
}return data;
}
//查看队首
int queue_ls_front(QUEUE_LS* queue)
{
return queue->front->data;
}
//元素数量
size_t queue_ls_size(QUEUE_LS* queue)
{
size_t size = 0;
QUEUE_NODE* find = queue->front;
for(; find; find = find->next)size++;
return size;
}
实现函数验证:
/**
*C实现:实现函数验证
*/
#include "chain.h"
int main()
{
int i;
QUEUE_LS queue_ls;
queue_ls_init(&queue_ls);//初始
for(i = 0; i < 5; i++){
queue_ls_push(&queue_ls, i+1);//入队
}
printf("队首=%d\n", queue_ls_front(&queue_ls));//队首
printf("数量=%d\n", queue_ls_size(&queue_ls));//数量
while(!queue_ls_empty(&queue_ls)){//判断空,不再出队
printf("%d\n", queue_ls_pop(&queue_ls));//出队
}
queue_ls_deinit(&queue_ls);//释放
return 0;
}
结果:
下一篇单向链表,受益匪浅,侵权立删,蟹蟹