数据结构简记✏️ | 哈希表&广义表

哈希表(Hash Table)

一、哈希表部分概念

  • 哈希函数 H ( k e y ) : K → D , k e y ∈ K H(key):K\to D,key\in K H(key):KD,keyK
  • 冲突:不同关键字的哈希函数可能相同,即 H ( k e y 1 ) = H ( k e y 2 ) , k e y 1 ≠ k e y 2 H(key_1)=H(key_2),key_1\ne key_2 H(key1)=H(key2),key1=key2这种现象称为冲突, k e y 1 , k e y 2 key_1,key_2 key1,key2称为同义词。😻
  • 哈希表:假设有8个关键字 22 , 41 , 53 , 46 , 30 , 13 , 12 , 67 22,41,53,46,30,13,12,67 22,41,53,46,30,13,12,67,地址区间长度为 11 11 11,哈希函数为 H ( k e y ) = k e y % 11 H(key)=key\%11 H(key)=key%11
  1. 若处理冲突方式为链地址法,如图
  2. 若处理冲突方式为线性探测法,如图

二、哈希函数的部分构造方法

1. 直接定址法

  • 哈希函数 H ( k e y ) = a × k e y + b H(key)=a\times key+b H(key)=a×key+b其中 a a a为缩放系数, b b b为平移系数。😸
  • 函数定义
int hash_d(int key){
	return a*key+b;
}

2. 除留余数法

  • 哈希函数 H ( k e y ) = k e y % p ( p ≤ m ) H(key)=key\%p(p\le m) H(key)=key%p(pm)其中 m m m是哈希表的长度, p p p最好取不大于 m m m素数。😺
  • 函数定义
int hash_m(int key){
	return key%p;
}

三、处理冲突的方法

1. 链地址法

  • 链地址法:将关键字为同义词的记录链接在同一个单链表中。😼
  • 链地址哈希表类型定义
typedef struct Node {
	RcdType r;
	struct Node *next;
}Node;
typedef struct {
	Node **rcd;//二重指针,大小动态分配
	int size;//哈希表容量
	int count;//当前哈希表中含有的记录个数
	int (*hash)(KeyType key, int hashSize);//函数指针变量,选取的哈希函数
}HashTable;//哈希表

2. 开放定址法

  • 线性探测法 H i = ( H ( k e y ) + i ) % m , 1 ≤ i ≤ m − 1 H_i=(H(key)+i)\%m,1\le i\le m-1 Hi=(H(key)+i)%m,1im1
  • 二次探测法 H i = ( H ( k e y ) + d i ) % m , 1 ≤ i ≤ m − 1 H_i=(H(key)+d_i)\%m,1\le i\le m-1 Hi=(H(key)+di)%m,1im1其中 d i = 1 , − 1 , 2 2 , − 2 2 , … k 2 , − k 2 ( k ≤ m / 2 ) d_i=1,-1,2^2,-2^2,\ldots k^2,-k^2(k\le m/2) di=1,1,22,22,k2,k2(km/2)
  • 开放定址哈希表类型定义:😽
typedef struct {
	RcdType *rcd;//记录存储基址,动态分配数组
	int size;//哈希表容量
	int count;//当前哈希表中含有的记录个数
	int *tag;//标记,0:空;1:有效;-1:已删除
	int (*hash)(KeyType key, int hashSize);
	void (*collision)(int &hashValue, int hashSize);//函数指针变量,用于处理冲突的函数
}HashTable;

广义表(Generalized List)

一、广义表部分概念

  • 一般记法 L = ( α 1 , α 2 , … α n ) L=(\alpha_1,\alpha_2,\ldots\alpha_n) L=(α1,α2,αn)
  • 原子和子表:对于广义表 L = α L=\alpha L=α α \alpha α称为原子, L L L称为子表。
  • 表头和表尾:对于广义表 L = ( α 1 , α 2 , … α n ) L=(\alpha_1,\alpha_2,\ldots\alpha_n) L=(α1,α2,αn) α \alpha α为表头, ( α 2 , … α n ) (\alpha_2,\ldots\alpha_n) (α2,αn)为表尾,表尾一定也是一个广义表。😿

二、广义表的存储结构

  • 类型定义:😾
typedef char AtomType;
typedef enum {
	ATOM,LIST  //ATOM值为0表示原子;LIST值为1表示表结点
}ElemTag;
typedef struct GLNode {
	ElemTag tag;//区分原子结点和表结点
	union {      //原子结点和表结点共用存储空间  
		AtomType atom;//当tag==ATOM时,本项有意义,存放原子结点值
		struct {      //当tag==LIST时,本项有意义
			struct GLNode *hp;
			struct GLNode *tp;
		}ptr;//表结点的指针域,其中ptr.hp指向表头,ptr.tp指向表尾
	}un;
}GLNode,*GList;//广义表
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值