C语言实现常见的数据结构

栈是一种后进先出(LIFO, Last In First Out)的数据结构

#include <stdio.h>
#include <stdlib.h>#define MAX 100typedef struct {int data[MAX];int top;
} Stack;// 初始化栈
void init(Stack *s) {s->top = -1;
}// 判断栈是否为空
int isEmpty(Stack *s) {return s->top == -1;
}// 判断栈是否满
int isFull(Stack *s) {return s->top == MAX - 1;
}// 入栈
void push(Stack *s, int value) {if (isFull(s)) {printf("Stack overflow!\n");return;}s->data[++s->top] = value;
}// 出栈
int pop(Stack *s) {if (isEmpty(s)) {printf("Stack underflow!\n");exit(1);}return s->data[s->top--];
}// 打印栈
void printStack(Stack *s) {for (int i = 0; i <= s->top; i++) {printf("%d ", s->data[i]);}printf("\n");
}int main() {Stack s;init(&s);push(&s, 10);push(&s, 20);push(&s, 30);printStack(&s);pop(&s);printStack(&s);return 0;
}

队列

队列是一种先进先出(FIFO, First In First Out)的数据结构。

循环队列

#include <stdio.h>
#include <stdlib.h>#define MAX 100typedef struct {int data[MAX];int front;int rear;
} Queue;// 初始化队列
void init(Queue *q) {q->front = 0;q->rear = 0;
}// 判断队列是否为空
int isEmpty(Queue *q) {return q->front == q->rear;
}// 判断队列是否满
int isFull(Queue *q) {return (q->rear + 1) % MAX == q->front;
}// 入队
void enqueue(Queue *q, int value) {if (isFull(q)) {printf("Queue overflow!\n");return;}q->data[q->rear] = value;q->rear = (q->rear + 1) % MAX;
}// 出队
int dequeue(Queue *q) {if (isEmpty(q)) {printf("Queue underflow!\n");exit(1);}int value = q->data[q->front];q->front = (q->front + 1) % MAX;return value;
}// 打印队列
void printQueue(Queue *q) {for (int i = q->front; i != q->rear; i = (i + 1) % MAX) {printf("%d ", q->data[i]);}printf("\n");
}int main() {Queue q;init(&q);enqueue(&q, 10);enqueue(&q, 20);enqueue(&q, 30);printQueue(&q);dequeue(&q);printQueue(&q);return 0;
}

平衡二叉树 (AVL Tree)

AVL树是一种自平衡二叉搜索树,任何节点的左右子树高度差不超过1。

#include <stdio.h>
#include <stdlib.h>// 定义节点
typedef struct Node {int key;struct Node *left;struct Node *right;int height;
} Node;// 获取节点的高度
int height(Node *n) {if (n == NULL) return 0;return n->height;
}// 创建新节点
Node* newNode(int key) {Node* node = (Node*)malloc(sizeof(Node));node->key = key;node->left = node->right = NULL;node->height = 1;return node;
}// 右旋转
Node* rightRotate(Node* y) {Node* x = y->left;Node* T2 = x->right;x->right = y;y->left = T2;y->height = 1 + fmax(height(y->left), height(y->right));x->height = 1 + fmax(height(x->left), height(x->right));return x;
}// 左旋转
Node* leftRotate(Node* x) {Node* y = x->right;Node* T2 = y->left;y->left = x;x->right = T2;x->height = 1 + fmax(height(x->left), height(x->right));y->height = 1 + fmax(height(y->left), height(y->right));return y;
}// 获取平衡因子
int getBalance(Node* n) {if (n == NULL) return 0;return height(n->left) - height(n->right);
}// 插入节点
Node* insert(Node* node, int key) {if (node == NULL) return newNode(key);if (key < node->key)node->left = insert(node->left, key);else if (key > node->key)node->right = insert(node->right, key);elsereturn node;node->height = 1 + fmax(height(node->left), height(node->right));int balance = getBalance(node);// 平衡调整if (balance > 1 && key < node->left->key)return rightRotate(node);if (balance < -1 && key > node->right->key)return leftRotate(node);if (balance > 1 && key > node->left->key) {node->left = leftRotate(node->left);return rightRotate(node);}if (balance < -1 && key < node->right->key) {node->right = rightRotate(node->right);return leftRotate(node);}return node;
}// 中序遍历
void inorder(Node* root) {if (root != NULL) {inorder(root->left);printf("%d ", root->key);inorder(root->right);}
}int main() {Node* root = NULL;root = insert(root, 10);root = insert(root, 20);root = insert(root, 30);root = insert(root, 40);root = insert(root, 50);inorder(root);return 0;
}

最优二叉树(哈夫曼树)的实现

哈夫曼树是一种用于数据压缩的二叉树。它是一种最优的前缀编码树,使用频率最低的字符分配最长的编码,从而达到压缩的效果。

#include <stdio.h>
#include <stdlib.h>// 定义哈夫曼树的节点
typedef struct Node {char data;int freq;struct Node *left, *right;
} Node;// 创建一个新的节点
Node* newNode(char data, int freq) {Node* node = (Node*)malloc(sizeof(Node));node->data = data;node->freq = freq;node->left = node->right = NULL;return node;
}// 交换两个节点
void swap(Node** a, Node** b) {Node* temp = *a;*a = *b;*b = temp;
}// 小顶堆 (Min Heap) 结构
typedef struct MinHeap {int size;int capacity;Node** array;
} MinHeap;// 创建一个小顶堆
MinHeap* createMinHeap(int capacity) {MinHeap* minHeap = (MinHeap*)malloc(sizeof(MinHeap));minHeap->size = 0;minHeap->capacity = capacity;minHeap->array = (Node**)malloc(minHeap->capacity * sizeof(Node*));return minHeap;
}// 堆化 (Heapify)
void minHeapify(MinHeap* minHeap, int idx) {int smallest = idx;int left = 2 * idx + 1;int right = 2 * idx + 2;if (left < minHeap->size && minHeap->array[left]->freq < minHeap->array[smallest]->freq)smallest = left;if (right < minHeap->size && minHeap->array[right]->freq < minHeap->array[smallest]->freq)smallest = right;if (smallest != idx) {swap(&minHeap->array[smallest], &minHeap->array[idx]);minHeapify(minHeap, smallest);}
}// 提取最小值节点
Node* extractMin(MinHeap* minHeap) {Node* temp = minHeap->array[0];minHeap->array[0] = minHeap->array[minHeap->size - 1];--minHeap->size;minHeapify(minHeap, 0);return temp;
}// 插入节点到堆
void insertMinHeap(MinHeap* minHeap, Node* node) {++minHeap->size;int i = minHeap->size - 1;while (i && node->freq < minHeap->array[(i - 1) / 2]->freq) {minHeap->array[i] = minHeap->array[(i - 1) / 2];i = (i - 1) / 2;}minHeap->array[i] = node;
}// 创建并构建小顶堆
MinHeap* buildMinHeap(char data[], int freq[], int size) {MinHeap* minHeap = createMinHeap(size);for (int i = 0; i < size; ++i)minHeap->array[i] = newNode(data[i], freq[i]);minHeap->size = size;for (int i = (minHeap->size - 2) / 2; i >= 0; --i)minHeapify(minHeap, i);return minHeap;
}// 构建哈夫曼树
Node* buildHuffmanTree(char data[], int freq[], int size) {Node *left, *right, *top;MinHeap* minHeap = buildMinHeap(data, freq, size);while (minHeap->size != 1) {left = extractMin(minHeap);right = extractMin(minHeap);top = newNode('$', left->freq + right->freq);top->left = left;top->right = right;insertMinHeap(minHeap, top);}return extractMin(minHeap);
}// 打印哈夫曼编码
void printCodes(Node* root, int arr[], int top) {if (root->left) {arr[top] = 0;printCodes(root->left, arr, top + 1);}if (root->right) {arr[top] = 1;printCodes(root->right, arr, top + 1);}if (!root->left && !root->right) {printf("%c: ", root->data);for (int i = 0; i < top; ++i)printf("%d", arr[i]);printf("\n");}
}// 哈夫曼编码主函数
void HuffmanCodes(char data[], int freq[], int size) {Node* root = buildHuffmanTree(data, freq, size);int arr[100], top = 0;printCodes(root, arr, top);
}int main() {char arr[] = { 'a', 'b', 'c', 'd', 'e', 'f' };int freq[] = { 5, 9, 12, 13, 16, 45 };int size = sizeof(arr) / sizeof(arr[0]);HuffmanCodes(arr, freq, size);return 0;
}

B树的实现

B树是一种多路自平衡的搜索树,常用于数据库和文件系统。以下是B树的基本实现。

 

#include <stdio.h>
#include <stdlib.h>#define T 3  // B树的最小度数// 定义B树的节点
typedef struct BTreeNode {int keys[2*T-1];     // 存储键struct BTreeNode* C[2*T]; // 存储子节点指针int n;            // 当前节点存储的键数量int leaf;         // 是否为叶子节点
} BTreeNode;// 创建一个B树节点
BTreeNode* createNode(int leaf) {BTreeNode* node = (BTreeNode*)malloc(sizeof(BTreeNode));node->leaf = leaf;node->n = 0;for (int i = 0; i < 2*T; i++) {node->C[i] = NULL;}return node;
}// 在非满节点插入键
void insertNonFull(BTreeNode* node, int k) {int i = node->n - 1;if (node->leaf) {while (i >= 0 && node->keys[i] > k) {node->keys[i + 1] = node->keys[i];i--;}node->keys[i + 1] = k;node->n++;} else {while (i >= 0 && node->keys[i] > k) {i--;}i++;if (node->C[i]->n == 2*T-1) {splitChild(node, i, node->C[i]);if (node->keys[i] < k) {i++;}}insertNonFull(node->C[i], k);}
}// 分裂子节点
void splitChild(BTreeNode* parent, int i, BTreeNode* fullChild) {BTreeNode* newChild = createNode(fullChild->leaf);newChild->n = T - 1;for (int j = 0; j < T-1; j++) {newChild->keys[j] = fullChild->keys[j + T];}if (!fullChild->leaf) {for (int j = 0; j < T; j++) {newChild->C[j] = fullChild->C[j + T];}}fullChild->n = T - 1;for (int j = parent->n; j >= i + 1; j--) {parent->C[j + 1] = parent->C[j];}parent->C[i + 1] = newChild;for (int j = parent->n - 1; j >= i; j--) {parent->keys[j + 1] = parent->keys[j];}parent->keys[i] = fullChild->keys[T - 1];parent->n++;
}// 插入一个键到B树
void insert(BTreeNode** root, int k) {BTreeNode* r = *root;if (r->n == 2*T-1) {BTreeNode* s = createNode(0);*root = s;s->C[0] = r;splitChild(s, 0, r);insertNonFull(s, k);} else {insertNonFull(r, k);}
}// 中序遍历B树
void traverse(BTreeNode* root) {int i;// 中序遍历节点中的所有键for (i = 0; i < root->n; i++) {// 如果不是叶子节点,先遍历子树if (!root->leaf) {traverse(root->C[i]);}printf("%d ", root->keys[i]);}// 最后遍历最右子树if (!root->leaf) {traverse(root->C[i]);}
}// 搜索键 k
BTreeNode* search(BTreeNode* root, int k) {int i = 0;// 查找当前节点中的键while (i < root->n && k > root->keys[i]) {i++;}// 找到键,返回当前节点if (i < root->n && k == root->keys[i]) {return root;}// 如果是叶子节点,说明键不存在if (root->leaf) {return NULL;}// 继续在子树中查找return search(root->C[i], k);
}int main() {BTreeNode* root = createNode(1); // 创建一个空的B树节点作为根节点// 插入一些键到B树中insert(&root, 10);insert(&root, 20);insert(&root, 5);insert(&root, 6);insert(&root, 12);insert(&root, 30);insert(&root, 7);insert(&root, 17);printf("Traversal of the constructed B-Tree is:\n");traverse(root);printf("\n");int key = 6;BTreeNode* result = search(root, key);if (result != NULL) {printf("Key %d found in B-Tree.\n", key);} else {printf("Key %d not found in B-Tree.\n", key);}return 0;
}
代码说明
  1. createNode: 创建一个新的B树节点。

  2. insertNonFull: 向一个非满节点插入一个键。

  3. splitChild: 分裂一个满节点为两个节点。

  4. insert: 插入一个新的键到B树中。

  5. traverse: 中序遍历B树,输出所有节点的键。

  6. search: 在B树中搜索一个键,找到则返回包含该键的节点,否则返回NULL

执行效果
  1. 插入了几个键后,树中将进行自动分裂和调整以保持B树的平衡特性。

  2. 使用traverse函数将打印B树中的所有键。

  3. 使用search函数可以在B树中搜索某个键并返回结果。

如果需要对B树进行更复杂的操作(如删除节点),可以继续扩展此基础实现。B树广泛用于数据库索引和文件系统管理,非常适合处理大规模数据。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/54904.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VBA技术资料MF204:右键多按钮弹出菜单中使用图标

我给VBA的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。“VBA语言専攻”提供的教程一共九套&#xff0c;分为初级、中级、高级三大部分&#xff0c;教程是对VBA的系统讲解&#…

【python】【绘制小程序】动态爱心绘制

背景介绍 参考链接&#xff1a;https://blog.csdn.net/Python_HUHU/article/details/139703289点的背景颜色在开始修改&#xff1b;文字的颜色在最后修改。文字内容可以修改。 python 代码 import tkinter as tk import random from math import sin, cos, pi, log from PIL…

Cocos 3.8.3 实现外描边效果(逃课玩法)

本来想着用Cocos 的Shader Graph照搬Unity的思路来加外描边&#xff0c;发现不行&#xff0c;然后我就想弄两个物体不就行了吗&#xff0c;一个是放大的版本&#xff0c;再放大的版本上加一个材质&#xff0c;这个材质面剔除选择前面的面剔除就行了&#xff0c;果不其然还真行。…

如何使用ssm实现基于java web的防疫工作志愿者服务平台的设计与实现

TOC ssm693基于java web的防疫工作志愿者服务平台的设计与实现jsp 绪论 1.1 研究背景 当前社会各行业领域竞争压力非常大&#xff0c;随着当前时代的信息化&#xff0c;科学化发展&#xff0c;让社会各行业领域都争相使用新的信息技术&#xff0c;对行业内的各种相关数据进…

详细解读,F5服务器负载均衡的技术优势

在现代大规模、高流量的网络使用场景中&#xff0c;为应对高并发和海量数据的挑战&#xff0c;服务器负载均衡技术应运而生。但凡知道服务器负载均衡这一名词的&#xff0c;基本都对F5有所耳闻&#xff0c;因为负载均衡正是F5的代表作&#xff0c;换句通俗易懂的话来说&#xf…

makefile和CMakeLists/C++包管理器

make 大家可能会很奇怪&#xff0c;都什么年代了&#xff0c;还学makefile&#xff0c;cmake都有些过时了&#xff0c;为什么还要再学这个呢&#xff1f; 我是这么看待这个问题的&#xff0c;cmake跨平台性还是很有有优势的&#xff0c;有着多年积累的底蕴&#xff0c;借助大模…

基于springboot的驾校预约管理系统的设计与实现 (含源码+sql+视频导入教程)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 基于springboot的驾校预约管理系统5拥有三种角色&#xff1a;管理员、教练、学员 管理员&#xff1a;学员管理、教练管理、车辆管理、车辆关联、维修管理等 教练&#xff1a;学员查看/毕…

再次重温 Spring 中 Bean 的生命周期

Bean的生命周期 Spring中的bean的生命周期主要包含四个阶段&#xff1a;实例化Bean --&#xff1e; Bean属性填充 --&#xff1e; 初始化Bean --&#xff1e;销毁Bean 首先是实例化Bean&#xff0c;当客户向容器请求一个尚未初始化的bean时&#xff0c;或初始化bean的时候需要…

hive-拉链表

目录 拉链表概述缓慢变化维拉链表定义 拉链表的实现常规拉链表历史数据每日新增数据历史数据与新增数据的合并 分区拉链表 拉链表概述 缓慢变化维 通常我们用一张维度表来维护维度信息&#xff0c;比如用户手机号码信息。然而随着时间的变化&#xff0c;某些用户信息会发生改…

SpringSecurity-用户认证

1、用户认证 1.1 用户认证核心组件 我们系统中会有许多用户&#xff0c;确认当前是哪个用户正在使用我们系统就是登录认证的最终目的。这里我们就提取出了一个核心概念&#xff1a;当前登录用户/当前认证用户。整个系统安全都是围绕当前登录用户展开的&#xff0c;这个不难理…

大数据新视界 --大数据大厂之HBase 在大数据存储中的应用与表结构设计

&#x1f496;&#x1f496;&#x1f496;亲爱的朋友们&#xff0c;热烈欢迎你们来到 青云交的博客&#xff01;能与你们在此邂逅&#xff0c;我满心欢喜&#xff0c;深感无比荣幸。在这个瞬息万变的时代&#xff0c;我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

如何进行Ubuntu磁盘空间深度清理?

近期使用AutoDL算力云&#xff0c;发现系统盘只有30G&#xff0c;数据盘只有50G&#xff0c;跑一个稍微大一点的模型&#xff0c;马上空间就拉爆了&#xff0c;现在做一个磁盘深度清理操作&#xff0c;看看效果。 清理前磁盘占用如下&#xff1a; 在 Ubuntu 系统中进行磁盘深度…

LabVIEW软件出现Bug如何解决

在LabVIEW开发中&#xff0c;程序出现bug是不可避免的。无论是小型项目还是复杂系统&#xff0c;调试与修复bug都是开发过程中的重要环节。下文介绍如何有效解决LabVIEW软件中的bug&#xff0c;包括常见错误类型、调试工具、错误处理机制。 1. 常见Bug类型分析 在LabVIEW中&am…

WGS1984快速度确定平面坐标系UTM分带(快速套表、公式计算、软件范围判定)

之前我们介绍了坐标系3带6带快速确定带号及中央经线&#xff08;快速套表、公式计算、软件范围判定&#xff09;就&#xff0c;讲的是CGCS2000 高斯克吕格的投影坐标系。 那还有我们经常用的WGS1984的平面坐标系一般用什么投影呢? 对于全球全国的比如在线地图使用&#xff1a…

计算机视觉硬件整理(四):相机与镜头参数介绍

文章目录 前言一、工业相机常用分类二、工业相机的基本参数三、工业相机的接口四、工业镜头的参数五、工业镜头的选择要点 前言 随着科技的飞速发展&#xff0c;工业自动化和智能制造在当今社会扮演着越来越重要的角色。在这个背景下&#xff0c;工业相机作为一种关键的视觉检…

面试系列-携程暑期实习一面

Java 基础 1、Java 中有哪些常见的数据结构&#xff1f; 图片来源于&#xff1a;JavaGuide Java集合框架图 Java 中常见的数据结构包含了 List、Set、Map、Queue&#xff0c;在回答的时候&#xff0c;只要把经常使用的数据结构给说出来即可&#xff0c;不需要全部记住 如下&…

SpringBoot集成阿里easyexcel(一)基础导入导出

easyexcel主要用于excel文件的读写&#xff0c;可使用model实体类来定义文件读写的模板&#xff0c;对开发人员来说实现简单Excel文件的读写很便捷。可参考官方文档 https://github.com/alibaba/easyexcel 一、引入依赖 <!-- 阿里开源EXCEL --><dependency><gr…

调用飞书接口导入供应商bug

1、业务背景 财务这边大部分系统都是供应商项目&#xff0c;由于供应商的研发人员没有飞书项目的权限&#xff0c;涉及到供应商系统需求 财务这边都是通过多维表格进行bug的生命周期管理如图&#xff1a; 但多维表格没有跟飞书项目直接关联&#xff0c;测试组做bug统计的时候无…

redis Redis-Cluster常用命令与Redis性能监控

起因&#xff1a;随着项目的进一步推广&#xff0c;数据量的增大&#xff0c;直接访问mysql数据库获取数据所使用的时间越来越长&#xff0c;为解决当前主要矛盾&#xff0c;决定引入redis非关系型数据库作为缓存层&#xff0c;使得数据并不能直接命中数据库&#xff0c;减少访…

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解

【洛谷】P10417 [蓝桥杯 2023 国 A] 第 K 小的和 的题解 题目传送门 题解 CSP-S1 补全程序&#xff0c;致敬全 A 的答案&#xff0c;和神奇的预言家。 写一下这篇的题解说不定能加 CSP 2024 的 RP 首先看到 k k k 这么大的一个常数&#xff0c;就想到了二分。然后写一个判…