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

数据结构 哈希表、栈的应用与链式队列 6.29 (尾)

前言

        来到这一篇博客,数据结构的这一阶段的学习也走向尾声。

        这一篇有三个内容:哈希表(通过链地址法处理哈希冲突),括号匹配(运用栈的特性进行实现),以及链式队列的实现。

概述

        1.哈希表

        2.括号匹配

        3.链式列队

1.哈希表

1.0 基本理论

        由于直接定址法在存储数据时由于数据不连续,容易导致浪费空间的现象。因此采用除留余数法。散列函数为:H(key)=key/p,p一般取数据长度除0.75之后的最接近的质数。

        但由于会出现多个数除留余数相等的情况,即哈希冲突。此时我们通过建立链表解决哈希冲突,如下图所示:

       

        之后是代码实现:

1.1.makefile

EXE=01_hash
Objs=$(patsubst %.c,%.o,$(wildcard *.c))
CC=gcc
CFlags=-c -oall:$(EXE)
$(EXE):$(Objs)$(CC) $^ -o $@
%.o:%.c$(CC) $^ $(CFlags) $@#伪目标
.PHONY:clean
clean:rm $(EXE) $(Objs)

1.2.hash.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 10
#define DEV 13typedef struct HashNode{union{int data;int len;};int result;struct HashNode* next;
}node,*node_p;typedef struct HashTable{node_p arr[DEV];
}table,*table_p;//fun
node_p create_head(int result);
node_p create_node(int value);
table_p create_Hash();
void sign_in_Hash(table_p T, int value);
void check(table_p T, int value);
void output(table_p T);#endif

1.3.fun.c

#include "hash.h"
//1
node_p create_head(int result){node_p H = (node_p)malloc(sizeof(node));H->len = 0;H->result = result;H->next = NULL;return H;
}
//2
node_p create_node(int value){node_p H = (node_p)malloc(sizeof(node));H->data = value;H->next = NULL;return H;
}
//3
table_p create_Hash(int len){if(len>MAX){printf("error\n");return NULL;}table_p H = (table_p)malloc(sizeof(table));for(int i = 0; i<=DEV-1; ++i){H->arr[i] = create_head(i);}return H;
}
//4
void sign_in_Hash(table_p T, int value){if(T == NULL){printf("error\n");return;}int result = value%13;for(int i = 0; i<=DEV-1; ++i){if(T->arr[i]->result == result){node_p new_p = create_node(value);node_p p = T->arr[i];p->len++;if(p->next!=NULL){new_p->next = p->next;}p->next = new_p;break;}}return;
}
//5
void check(table_p T, int value){if(T == NULL){printf("error\n");return;}int result = value%13;int flag = 0;node_p p = T->arr[result];while(p!=NULL){if(p->data == value){printf("exist\n");flag = 1;break;}p = p->next;}if(flag==0){printf("none\n");}return;
}
//6
void output(table_p T){if(T == NULL){printf("error\n");return;}for(int i = 0; i<=DEV-1; ++i){node_p p = T->arr[i]->next;while(p!=NULL){printf("%d ",p->data);p = p->next;}}printf("\n");return;
}

1.4.main.c

#include "hash.h"
int main(int argc, const char *argv[])
{int arr_start[10] = {25,51,8,22,26,67,11,16,54,41};table_p H = create_Hash(10);for(int i = 0; i<=9; ++i){sign_in_Hash(H,arr_start[i]);}check(H,22);output(H);free(p);p = NULL;return 0;
}

1.5.run

ubuntu@ubuntu:~/data_structre/vacation/hash$ ./01_hash 
exist
26 41 54 67 16 8 22 11 51 25 
ubuntu@ubuntu:~/data_structre/vacation/hash$ 

        对照上分图片,数据已经按哈希表的顺序排列好,数据的存入与查找也运作正常。

2.括号匹配(栈)

2.1.makefile

EXE=01_bracket
Objs=$(patsubst %.c,%.o,$(wildcard *.c))
CC=gcc
CFlags=-c -oall:$(EXE)
$(EXE):$(Objs)$(CC) $^ -o $@
%.o:%.c$(CC) $^ $(CFlags) $@#伪目标
.PHONY:clean
clean:rm $(EXE) $(Objs)

2.2.bracket.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAX 128typedef struct stack{char arr[MAX];int top;
}stack,*stack_p;//fun
stack_p create_stack();
void input(char* str);
void match(char a,char b);
void filter(stack_p S, char*str);#endif

2.3.fun.c

#include "bracket.h"
//create stack
stack_p create_stack(){stack_p S = (stack_p)malloc(sizeof(stack));memset(S,0,sizeof(stack));S->top=-1;return S;
}//1
void input(char* str){printf("请输入需要匹配括号的字符串:\n");scanf("%s",str);str[strcspn(str,"\n")]='\0';
}
//2
void match(char a,char b){if((a=='('&&b==')')\||(a=='['&&b==']')\||(a=='{'&&b=='}')){printf("matching successed\n");}else{printf("matching failed\n");}
}
//3
void filter(stack_p S, char*str){if(S==NULL){printf("error");return;}int len = strlen(str);for(int i = 0; i<=len-1; ++i){if(str[i]=='('\||str[i]=='['\||str[i]=='{'){S->top++;S->arr[S->top]=str[i];}if(str[i]==')'\||str[i]==']'\||str[i]=='}'){match(S->arr[S->top],str[i]);S->top--;}}//puts(S->arr);return;
}

2.4.main.c

#include "bracket.h"
int main(int argc, const char *argv[])
{char str[128]={0};input(str);stack_p S = create_stack();filter(S,str);return 0;
}   

2.5.run

ubuntu@ubuntu:~/data_structre/vacation/bracket$ ./01_bracket 
请输入需要匹配括号的字符串:
(dksdhjs)[]
matching successed
matching successed
ubuntu@ubuntu:~/data_structre/vacation/bracket$ ./01_bracket 
请输入需要匹配括号的字符串:
(dhshdj[)]
matching failed
matching failed

        注意,上图中的第二种情况括号错开实际上属于匹配失败,因此试图通过对左右括号计数来判断匹配性是有问题的(不要问我怎么知道的......)

3.链式列队

3.1.makefile

EXE=01_lque
Objs=$(patsubst %.c,%.o,$(wildcard *.c))
CC=gcc
CFlags=-c -oall:$(EXE)
$(EXE):$(Objs)$(CC) $^ -o $@
%.o:%.c$(CC) $^ $(CFlags) $@#伪目标
.PHONY:clean
clean:rm $(EXE) $(Objs)

3.2.lque.h

#ifndef _HEAD_H_
#define _HEAD_H_#include <stdio.h>
#include <string.h>
#include <stdlib.h>typedef struct queue{int data;struct queue* next;
}queue,*queue_p;typedef struct head{queue_p front;queue_p rear;
}head,*head_p;head_p create_head();
queue_p create_node(int value);
void input(head_p H,int value);
int output(head_p H);
void show(head_p H);
#endif

3.3.fun.c

#include "lque.h"
//1
head_p create_head(){head_p H = (head_p)malloc(sizeof(head));H->front = NULL;H->rear = NULL;return H;
}
//2
queue_p create_node(int value){queue_p Q = (queue_p)malloc(sizeof(queue));Q->data = value;Q->next = NULL;return Q;
}
//3
//列队的特性:尾进
void input(head_p H,int value){queue_p new = create_node(value);new->next = NULL;new->data = value;if(H->rear!=NULL){H->rear->next = new;}H->rear = new;if(H->front == NULL){H->front = new;}return;
}
//4
//头出
int output(head_p H){if(H->front == NULL)return -999;queue_p p_del = H->front;H->front = H->front->next;int out_data = p_del->data;free(p_del);return out_data;
}
//5
void show(head_p H){if(H->front == NULL)return;queue_p p = H->front;while(p!=NULL){printf("%d ",p->data);p=p->next;}printf("\n");return;
}

3.4.main.c

#include "lque.h"
int main(int argc, const char *argv[])
{head_p H = create_head();input(H,1);input(H,2);input(H,3);input(H,4);input(H,5);show(H);int num = output(H);printf("output:%d\n",num);printf("after:");show(H);return 0;
}  

3.5.run

ubuntu@ubuntu:~/data_structre/vacation/linked queue$ make
gcc main.c -c -o main.o
gcc fun.c -c -o fun.o
gcc main.o fun.o -o 01_lque
ubuntu@ubuntu:~/data_structre/vacation/linked queue$ ./01_lque 
1 2 3 4 5 
output:1
after:2 3 4 5 
ubuntu@ubuntu:~/data_structre/vacation/linked queue$ .

        尾进头出。

结语

        以上。

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

相关文章:

  • 现代 JavaScript (ES6+) 入门到实战(八):总结与展望 - 成为一名现代前端开发者
  • day46/60
  • H3C-路由器交换机-中继
  • 计算机组成原理与体系结构-实验一 进位加法器(Proteus 8.15)
  • 5 c++核心——文件操作
  • MySQL技巧
  • 如何优化RK3588集群的性能?支持12个RK3588云手机阵列
  • C++ 格式化输入输出
  • Java中对JSON的操作
  • 模拟多维物理过程与基于云的数值分析-AI云计算数值分析和代码验证
  • SpringCloud系列(41)--SpringCloud Config分布式配置中心简介
  • TCP/UDP协议深度解析(三):TCP流量控制的魔法—滑动窗口、拥塞控制与ACK的智慧
  • Java笔记
  • 野生动物检测数据集介绍-5,138张图片 野生动物保护监测 智能狩猎相机系统 生态研究与调查
  • 贝叶斯自学笔记——基础工具篇(一)
  • Python爬虫实战:研究Bleach库相关技术
  • 【linux】权限深入解析
  • [分布式并行] 流水线并行 PP(NaivePP/GPipe/F-then-B/PipeDream/1F1B)
  • #华为鲲鹏#华为计算#鲲鹏开发者计划2025#
  • 概率论符号和公式整理
  • 大模型小模型选型手册:开源闭源、国内国外全方位对比
  • 团结引擎发布纯鸿蒙应用
  • 微信小程序接入腾讯云短信验证码流程
  • python 使用 pyenv 管理 python 版本
  • 从代码学习深度学习 - 自然语言推断:使用注意力 PyTorch版
  • 基于Servlet + Jsp 的在线考试系统
  • 华为云Flexus+DeepSeek征文 | 华为云 ModelArts Studio 赋能高情商AI聊天助手:用技术构建有温度的智能对话体验
  • libevent(2)之使用教程(1)介绍
  • 基于云的平板挠度模拟:动画与建模-AI云计算数值分析和代码验证
  • 多模态大语言模型arxiv论文略读(143)