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.xdnf.cn/news/147316.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

黄酮类化合物及其衍生物生物合成的进展:构建酵母细胞工厂的系统策略-文献精读50

Advances in Flavonoid and Derivative Biosynthesis: Systematic Strategies for the Construction of Yeast Cell FactoriesCli 黄酮类化合物及其衍生物生物合成的进展&#xff1a;构建酵母细胞工厂的系统策略 摘要 黄酮类化合物是一类重要的天然多酚化合物&#xff0c;具有…

240922-MacOS终端访问硬盘

A. 最终效果 B. 操作步骤 在macOS中&#xff0c;可以通过命令行使用Terminal访问硬盘的不同位置。你可以按照以下步骤操作&#xff1a; 打开终端&#xff08;Terminal&#xff09;&#xff1a; 在应用程序中打开终端&#xff0c;或者使用 Spotlight 搜索“Terminal”来启动。 …

EnvironmentError: [Errno 28] No space left on device - 完美解决方法

&#x1f6a8;EnvironmentError: [Errno 28] No space left on device - 完美解决方法&#x1f4a1; &#x1f6a8;EnvironmentError: [Errno 28] No space left on device - 完美解决方法&#x1f4a1;摘要引言正文1. 错误解析&#xff1a;为什么会出现“No space left on dev…

线程池执行流程以及拒绝策略小结

线程池是一个用来创建、管理线程的工具&#xff0c;线程池内部维护了若干个线程&#xff0c;没有任务的时候&#xff0c;这些线程都处于等待空闲状态。如果有新的线程任务&#xff0c;就分配一个空闲线程执行。如果所有线程都处于忙碌状态&#xff0c;线程池会创建一个新线程进…

Linux 5.0在start_kernel之前做了什么事?(以aarch64为例)

目录 引言汇编启动&#xff01;&#xff01;&#xff01;细节剖析 引言 之前在研究Linux内核源码的时候总是找不到关于这部分源码的相关剖析&#xff0c;要么也是模棱两可的&#xff0c;也有一些比较专业的代码分析&#xff0c;不过比较分散&#xff0c;感觉大家都不太喜欢这部…

云计算第四阶段---CLOUD Day7---Day8

CLOUD 07 一、Dockerfile详细解析 指令说明FROM指定基础镜像&#xff08;唯一&#xff09;RUN在容器内执行命令&#xff0c;可以写多条ADD把文件拷贝到容器内&#xff0c;如果文件是 tar.xx 格式&#xff0c;会自动解压COPY把文件拷贝到容器内&#xff0c;不会自动解压ENV设置…

【Godot4.3】点数据简易表示法和Points2D

概述 在构造多点路径时我们会用到PackedVector2Array&#xff0c;并使用Vector2()来构造点。在手动创建多点数据时&#xff0c;这种写法其实很难看&#xff0c;有大量重复的Vector2()&#xff0c;比如下面这样&#xff1a; var points [Vector2(100,100),Vector2(200,200),V…

项目扩展二:消息拉取功能的实现

项目扩展二&#xff1a;消息拉取功能的实现 一、回顾一下消息推送功能是如何实现的二、设计消息拉取功能1.服务器如何处理2.定义Request和Response1.定义Request2.proto文件 三、服务器实现消息拉取1.业务模块的实现&#xff1a;信道模块2.消费者管理模块实现O(1)获取消费者1.目…

C++迭代器 iterator详解

目录 什么是迭代器 迭代器的类型 迭代器的用法 三种迭代器 范围for 什么是迭代器 它提供了一种访问容器&#xff08;如列表、集合等&#xff09;中元素的方法&#xff0c;而无需暴露容器的内部表示。迭代器使得程序员能够以统一的方式遍历不同的数据结构&#xff0c;而无需…

JVM的基本概念

目录 一、JVM的内存划分 二、JVM的类加载过程 三、JVM的垃圾回收机制&#xff08;GC&#xff09; 四、分代回收 一、JVM的内存划分 一个运行起来的Java进程&#xff0c;就是一个Java虚拟机&#xff0c;就需要从操作系统中申请一大块内存。申请的内存会划分为不同的区域&…

5.工欲善其事,必先利其器!收集金融数据你必须先做这个!

在正式从网络上获取数据并存储到我们的数据库之前&#xff0c;我们还需要做一些准备工作。其中最重要的无疑是把Python环境配置好。 你可以不好好学习Python&#xff0c;毕竟我后边会一步步教大家&#xff0c;也会提供现成的Python脚本。但是你必须得在你的电脑上把Python安装…

基于51单片机无线蓝牙智能家居控制系统设计

文章目录 前言资料获取设计介绍功能介绍设计程序具体实现截图![请添加图片描述](https://i-blog.csdnimg.cn/direct/c25dac9c3044416385d22a655dee5c3d.jpeg)设计获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师&#xff…

LLM安全风险及应对

LLM安全风险主要从四个维度分析&#xff1a;用户输入、训练数据、模型本身以及工具和插件。 风险类别具体风险风险解释应对措施具体举例用户输入相关风险提示注入&#xff08;Prompt Injection&#xff09;攻击者通过设计特定输入&#xff0c;使模型生成恶意或不安全的输出。- …

FLStudio21Mac版flstudio v21.2.1.3430简体中文版下载(含Win/Mac)

给大家介绍了许多FL21版本&#xff0c;今天给大家介绍一款FL Studio21Mac版本&#xff0c;如果是Mac电脑的朋友请千万不要错过&#xff0c;当然我也不会忽略掉Win系统的FL&#xff0c;链接我会放在文章&#xff0c;供大家下载与分享&#xff0c;如果有其他问题&#xff0c;欢迎…

【成神之路】Ambari实战-011-代码生命周期-metainfo加载原理深度剖析

在 Ambari 中&#xff0c;metainfo.xml 是定义服务和组件的关键配置文件。Ambari 通过解析它来加载和管理服务的整个生命周期。今天&#xff0c;我们将深入探索 metainfo.xml 是如何被解析的&#xff0c;并以 Redis 集群服务为例&#xff0c;逐步解读 Ambari 的处理过程。&…

cv中每个patch的关联

在计算机视觉任务中&#xff0c;当图像被划分为多个小块&#xff08;patches&#xff09;时&#xff0c;每个 patch 的关联性可以通过不同的方法来计算。具体取决于使用的模型和任务&#xff0c;以下是一些常见的计算 patch 关联性的方法&#xff1a; 1. Vision Transformer (…

Java : 图书管理系统

图书管理系统的作用&#xff1a; 高效的图书管理 图书管理系统通过自动化管理&#xff0c;实现了图书的采编、编目、流通管理等操作的自动化处理&#xff0c;大大提高了图书管理的效率和准确性。 工作人员可以通过系统快速查找图书信息&#xff0c;实时掌握图书的借还情况&…

【comfyUI工作流】一键生成专属欧美漫画!

现在你不需要在webui上手动设置一堆的参数 来将自己的照片转绘成欧美漫画插画 可以通过我制作的工作流一键完成转绘&#xff0c;更加效率便捷&#xff0c; 而且不需要你懂什么专业的AI绘画知识&#xff0c;会打开工作流&#xff0c;上传图片就可以 工作流特点 真实照片一键…

程序员的AI时代:拥抱变革,塑造未来

你们有没有想过&#xff0c;如果有一天&#xff0c;你的编程工作被一个AI助手取代了&#xff0c;你会怎么办&#xff1f;这不是危言耸听&#xff0c;随着AIGC技术的飞速发展&#xff0c;这样的场景可能真的会出现。但是&#xff0c;别担心&#xff0c;今天我们就来聊聊&#xf…

XSS—xss-labs靶场通关

level 1 JS弹窗函数alert() <script>alert()</script> level 2 闭合绕过 "> <script>alert()</script> <" level 3 onfocus事件在元素获得焦点时触发&#xff0c;最常与 <input>、<select> 和 <a> 标签一起使用…