飞书文档https://x509p6c8to.feishu.cn/wiki/HRLkwznHiiOgZqkqhLrcZNqVnLd
一、存储结构
顺序存储
链式存储
二、常用数据结构
2.1、栈
先进后出
场景:
后退/前进功能:网页浏览器中的后退和前进按钮可以使用栈来实现。在浏览网页时,每次访问一个新页面时,当前页面的信息将被推入栈中。当用户点击后退按钮时,程序将从栈中弹出最近的访问页面,并显示上一个页面。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_STACK_SIZE 100
typedef struct {
char url[MAX_STACK_SIZE];
} StackItem;
typedef struct {
StackItem items[MAX_STACK_SIZE];
int top;
} Stack;
void initStack(Stack *stack) {
stack->top = -1;
}
int isStackEmpty(Stack *stack) {
return stack->top == -1;
}
int isStackFull(Stack *stack) {
return stack->top == MAX_STACK_SIZE - 1;
}
void push(Stack *stack, char *url) {
if (isStackFull(stack)) {
printf("Stack overflow!\n");
return;
}
stack->top++;
strcpy(stack->items[stack->top].url, url);
}
char* pop(Stack *stack) {
if (isStackEmpty(stack)) {
printf("Stack underflow!\n");
return NULL;
}
char *url = stack->items[stack->top].url;
stack->top--;
return url;
}
int main() {
char inputurl[MAX_STACK_SIZE];
int choice;
Stack stack;
initStack(&stack);
while (1)
{
printf("------》1:入栈\n");
printf("------》2:出栈\n");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("请输入入栈内容:");
scanf("%s",inputurl);
push(&stack,inputurl);
printf("入栈成功\n");
break;
case 2:
if (!isStackEmpty(&stack)) {
char *url = pop(&stack);
printf("出栈:%s\n", url);
}else{
printf("已没有数据\n");
}
break;
default:
printf("无效操作\n");
break;
}
}
return 0;
}
2.2、队列
场景:
编写代码,实现演唱会购票用户(id、座位区域(A、B、C))购票与出票。
分析:
按购票顺序先后处理,先购票先出票
#include <stdio.h>
#define MAX_AREA_SIZE 10
#define MAX_QUEUE_SIZE 5
typedef struct {
int id;
char area[MAX_AREA_SIZE];
} User;
typedef struct {
User data[MAX_QUEUE_SIZE];
int front; //队列头位置
int rear; //队列尾位置
} Queue;
/**
* @brief 初始化队列
* 初始化时,由于队列为空,队列头和尾位置都在0
* @param q
*/
void initQueue(Queue *q) {
q->front = q->rear = 0;
}
/**
* @brief 判断队列是否为空
* 当队列头位置和尾位置相同时,队列为空
* @param q
* @return int
*/
int isQueueEmpty(Queue *q) {
return q->front == q->rear;
}
/**
* @brief 判断队列是否满
* 当队列尾位置+1等于队列头位置时,队列满(队列尾位置追上头位置)
* @param q
* @return int
*/
int isQueueFull(Queue *q) {
return (q->rear + 1) % MAX_QUEUE_SIZE == q->front;
}
/**
* @brief 入队
* 先判断队列是否满,然后存储数据到队列尾位置,队列尾位置+1
* @param q
* @param s
* @return int
*/
int enqueue(Queue *q, User *s) {
if (isQueueFull(q)) {
return 0;
}
printf("id=%d, area=%s ", s->id, s->area);
q->data[q->rear] = *s;
q->rear = (q->rear + 1) % MAX_QUEUE_SIZE;
return 1;
}
/**
* @brief 出队
* 先判断队列是否空,然后读取队列头的数据,队列头位置+1
* @param q
* @param s
* @return int
*/
int dequeue(Queue *q, User *s) {
if (isQueueEmpty(q)) {
return 0;
}
*s = q->data[q->front];
printf("id=%d, area=%s\n", s->id, s->area);
q->front = (q->front + 1) % MAX_QUEUE_SIZE;
return 1;
}
int main() {
int id = 0;
User user;
int choice;
Queue q;
initQueue(&q);
while (1)
{
printf("------》1:顾客购票\n");
printf("------》2:工作人员出票\n");
scanf("%d",&choice);
switch (choice)
{
case 1:
printf("请输入购票区域:");
user.id = id ++;
scanf("%s",user.area);
if(enqueue(&q, &user) == 1)
printf("支付成功,等待工作人员处理\n");
else
printf("支付失败,当前无票\n");
break;
case 2:
printf("出票:");
User s;
if (!dequeue(&q, &s)) {
printf("已没有购票需要处理\n");
}
break;
default:
printf("无效操作\n");
break;
}
}
return 0;
}
2.3、链表
场景:实现一个用户信息管理系统,支持插入、查找、删除
分析:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义用户结构体
typedef struct User {
char name[50];
int age;
struct User *next;
} User;
// 初始化链表头节点
User *head = NULL;
// 插入用户信息
void insertUser() {
User *newUser = (User *) malloc(sizeof(User));
printf("请输入用户名:");
scanf("%s", newUser->name);
printf("请输入年龄:");
scanf("%d", &newUser->age);
newUser->next = NULL;
if (head == NULL) {
head = newUser;
} else {
User *temp = head;
while (temp->next != NULL) {
temp = temp->next;
}
temp->next = newUser;
}
printf("用户信息插入成功!\n");
}
// 删除用户信息
void deleteUser() {
if (head == NULL) {
printf("链表为空,无法删除用户信息!\n");
return;
}
char name[50];
printf("请输入要删除的用户名:");
scanf("%s", name);
User *temp = head;
User *prev = NULL;
while (temp != NULL && strcmp(temp->name, name) != 0) {
prev = temp;
temp = temp->next;
}
if (temp == NULL) {
printf("未找到要删除的用户信息!\n");
return;
}
if (prev == NULL) {
head = temp->next;
} else {
prev->next = temp->next;
}
free(temp);
printf("用户信息删除成功!\n");
}
// 查找用户信息
void findUser() {
if (head == NULL) {
printf("链表为空,无法查找用户信息!\n");
return;
}
char name[50];
printf("请输入要查找的用户名:");
scanf("%s", name);
User *temp = head;
while (temp != NULL && strcmp(temp->name, name) != 0) {
temp = temp->next;
}
if (temp == NULL) {
printf("未找到要查找的用户信息!\n");
} else {
printf("用户名:%s,年龄:%d\n", temp->name, temp->age);
}
}
int main() {
int choice;
while (1) {
printf("请选择要执行的操作:\n");
printf("1. 插入用户信息\n");
printf("2. 删除用户信息\n");
printf("3. 查找用户信息\n");
printf("4. 退出程序\n");
printf("请输入操作编号:");
scanf("%d", &choice);
switch (choice) {
case 1:
insertUser();
break;
case 2:
deleteUser();
break;
case 3:
findUser();
break;
case 4:
exit(0);
default:
printf("输入的操作编号有误,请重新输入!\n");
break;
}
}
return 0;
}