当前位置: 首页 > web >正文

玳瑁的嵌入式日记D24-0823(数据结构)

散列表(哈希表)

typedef int DATATYPE;

typedef struct {
DATATYPE *head;
int tlen;

}HS_Table;

HS_Table *CreateHsTable(int len)

HS_Table *hs = (HS_Table *)malloc(sizeof(HS_Table)); //分配 HS_Table 结构体的内存空间
if(NULL == hs)
{
perror("malloc1 error\n");
return NULL;
}
hs->head = (DATATYPE *)malloc(sizeof(DATATYPE) * len); //为存储数据的数组分配内存空间
if(NULL == hs->head)
{
perror("malloc2 error\n");
return NULL;
}
hs->tlen = len;
int i = 0;
for(i = 0; i < len; i++)
{
hs->head[i] = -1;
//将数组所有元素初始化为 -1,表示空位置
return hs;
}

/**
* @brief 根据需要存储的数据,计算下标
  FUN 1.计算过程尽可能简单      2.下标均匀分布
*/
int HS_Fun(HS_Table *h, DATATYPE *data)
{
return *data % h->tlen;
//使用除留余数法计算数据在表中的位置

int HS_Insert(HS_Table *h, DATATYPE *data)
{
int ind = HS_Fun(h, data);
//hash表的空间,一定要大于等于需要存储的数据的个数
while(h->head[ind] != -1)
{
printf("data:%d  ind:%d\n",*data, ind);
ind = (ind + 1) % h->tlen;  // 如果当前位置已被占用,则检查下一个位置(循环方式)
}
memcpy(&h->head[ind], data, sizeof(DATATYPE));
return 0;
}

int HS_Search(HS_Table*h,DATATYPE* data)
{
int ind = HS_Fun(h, data);
int old_ind = ind;
while(h->head[ind] != *data)
{
ind = (ind + 1) % h->tlen;
if(ind == old_ind)   //如果回到起始位置仍未找到,说明数据不存在,返回 -1
{
return -1;
}

}
return ind;
}

int HS_Destroy(HS_Table *h)
{
free(h->head);
free(h);
return 0;
}

int    main(int argc, char **argv)
{
HS_Table *hs = CreateHsTable(12);
int array[12] = {12,67,56,16,25,37,22,29,15,47,48,34};

    for(int i = 0; i < 12; i++)
{
HS_Insert(hs, &array[i]);
}
int want_num = 22;
int ret = HS_Search(hs, &want_num);
if(ret == -1)
{
printf("not find  %d\n",want_num);
}
else
{
printf("find %d\n", want_num);
}
HS_Destroy(hs);

    //system("pause");
return 0;
}


排序

快速排序

左指针 left 指向数组起始位置,右指针 right 指向数组末尾
左指针向右移动,直到找到大于等于基准值的元素。
右指针向左移动,直到找到小于等于基准值的元素。
交换两个指针指向的元素,重复步骤 2-3,直到 left ≥ right
交换基准值与 right 指针指向的元素(此时基准值被放到正确位置)。

#include <stdio.h>

// 交换两个元素的值
void swap(int* a, int* b) {
int temp = *a;
*a = *b;
*b = temp;
}

// 分区函数:返回基准值最终位置
int partition(int arr[], int low, int high) {
int pivot = arr[low];  // 选择最左侧元素作为基准值
int left = low;        // 左指针
int right = high;      // 右指针

    while (left < right)

{
// 左指针向右移动,直到找到大于等于基准值的元素
while (arr[left] < pivot)

        {
left++;
}
// 右指针向左移动,直到找到小于等于基准值的元素
while (arr[right] > pivot)

         {
right--;
}
// 交换左右指针指向的元素
if (left < right) {
swap(&arr[left], &arr[right]);
}
}
// 将基准值放到正确位置(与右指针交换)
swap(&arr[low], &arr[right]);
return right;  // 返回基准值位置
}

// 快速排序递归函数
void quickSort(int arr[], int low, int high) {
if (low < high) {
// 划分区间,获取基准值位置
int   pivotPos = partition(arr, low, high);
// 递归排序左侧子数组
quickSort(arr, low, pivotPos - 1);


        // 递归排序右侧子数组
quickSort(arr, pivotPos + 1, high);

}
}


KLIST 内核链表(Kernel Linked List)

#include "list.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

/**
* @brief 这个是内核链表的一个demo
*     1. 第一自己需要的数据类型  ,其中必须包含一个 struct list_head 的变量
2. 定义头节点,并初始化
3. 增加结点,malloc自己的结构体,填入自己需要的数据 调用list_add,把当前结点加入链表
4. 遍历所有元素list_for_each_entry_safe,
*/
typedef struct {
int id;
char name[20];
struct list_head node;
}PER;

int add_per(struct list_head *head, int id, char *name)
{
PER *per = malloc(sizeof(PER));
if(NULL == per)
{
printf("malloc error\n");
return -1;
}
per->id = id;
strcpy(per->name, name);
//list_add(&per->node, head);
list_add_tail(&per->node, head);
return 0;
}

int show(struct list_head *head)
{
PER *tmp;
PER *next;
list_for_each_entry_safe(tmp, next, head, node)
{
printf("id:%d, name:%s\n", tmp->id, tmp->name);
}
return 0;
}
int del_per(struct list_head *head, int id)

PER *tmp;
PER *next;
list_for_each_entry_safe(tmp, next, head, node)
{
if (tmp->id == id)
{
list_del(&tmp->node);
free(tmp);
}
}
return 0;
}

int find_per(struct list_head *head, int id)
{
PER *tmp;
PER *next;
list_for_each_entry_safe(tmp, next, head, node)
{
if(tmp->id == id)
{
printf("find  id:%d, name:%s\n", tmp->id, tmp->name);
}

return 0;
}

int modify_per(struct list_head *head, int id,char *new_name,int new_id)
{
PER *tmp;
PER *next;
list_for_each_entry_safe(tmp, next, head, node)
{
if(tmp->id == id)
{
if(new_name)
{
strcpy(tmp->name, new_name);
}
id = new_id;
}

return 0;
}

int    main(int argc, char **argv)
{
struct list_head head;
  //双向循环链表,当前结点的prev,next 都指向自己
INIT_LIST_HEAD(&head);

    add_per(&head, 1, "zhagnsan");
add_per(&head, 2, "lisi");
add_per(&head, 3, "wangmazi");
add_per(&head, 4, "guanerge");
add_per(&head, 5, "liubei ");

  show(&head);
del_per(&head, 1);
printf("------------del--------------\n");
modify_per(&head, 2, "lisi2",5);
show(&head);

    //system("pause");
return 0;
}

http://www.xdnf.cn/news/18694.html

相关文章:

  • 【基础-判断】使用http模块发起网络请求时,必须要使用on(‘headersReceive’)订阅请求头,请求才会成功。
  • 游戏广告投放数据分析项目:拆解投放的“流量密码”
  • 图像边缘检测
  • qwen2.5vl(2):lora 微调训练及代码讲解
  • Android Studio下载gradle文件很慢的捷径之路
  • 个人禁食伴侣FastTrack
  • 数据库类型与应用场景全解析:从传统关系型到新兴向量数据库
  • MySQL深分页的处理方案
  • React学习(十一)
  • 深入理解 React useEffect
  • 三、Bpmnjs 核心组件与架构介绍
  • 【c++进阶系列】:万字详解多态
  • 分库分表系列-基础内容
  • piecewise jerk算法介绍
  • 密码实现安全基础篇 . KAT(已知答案测试)技术解析与实践
  • SpringBoot自动配置原理解析
  • Reactor 反应堆模式
  • 游游的数组询问
  • SOC估算方法-蜣螂优化算法结合极限学习
  • NVIDIA Nsight Systems性能分析工具
  • 【Linux系统】进程信号:信号的处理
  • 【基础-判断】订阅dataReceiveProgress响应事件是用来接收HTTP流式响应数据。
  • 基于LLM的跨架构物联网静态漏洞挖掘检测 摘要
  • Ubuntu2204server系统安装postgresql14并配置密码远程连接
  • 小程序备案话术
  • 关于微服务下的不同服务之间配置不能通用的问题
  • pid自适应调节实战设计-基于输出电流的PI参数切换方案
  • React Hooks原理深潜:从「黑魔法」到「可观测」的蜕变之旅
  • Linux服务器Systemctl命令详细使用指南
  • DeepSeek V3.1 横空出世:重新定义大语言模型的边界与可能