散列技术之链地址法(基于无序链表)

源码例如以下:

#include <stdlib.h>
#include <stdio.h>
#define hash(v,M) (v % M)
typedef char Key;
struct Item{
	Key key;
};
typedef struct STnode* link;
struct STnode{
	Item item ; link next;
};

static link* heads , z ;
static struct Item NULLitem ;
static int N , M ;

Key key(Item item){
	return item.key;
}
//创建一个节点
static link NEW(Item item, link next){
	link x = (link)malloc(sizeof *x);
	x->item = item;x->next = next;
	return x;
}
//初始化
void STinit(int max){
	int i ;
	N = 0; M = max / 5;
	heads = (link *)malloc(M*sizeof(link));
	z = NEW(NULLitem,NULL);
	for(i=0;i<M;i++)heads[i] = z;
}
//节点个数
int STcount(){
	return N;
}
//搜索子程序
Item searchR(link h, Key v){
	Key t = key(h->item);
	if(h==z)return NULLitem;
	if(v==t) return h->item;
	return searchR(h->next,v);
}
//搜索主程序
Item STsearch(Key v){
	return searchR(heads[hash(v,M)],v);
}

//插入主程序
void STinsert(Item item){
	int i = hash(key(item),M) ;
	heads[i] = NEW(item,heads[i]); N++;
}

//单链表删除指定的节点  非递归
link deleteT(link head,Item v){
	link node1=head;
	link node2=NULL;
	if (head==NULL)return NULL;
	if (node1->item.key==v.key){
		head=head->next;
		free(node1);
		return head;
	}
	while (node1!=NULL){
		node2=node1;
		node2=node2->next;
		if (node2->item.key==v.key){
			node1->next=node2->next;
			free(node2);
			break;
		}
		node1=node1->next;
	}
	return head;
}

//单链表删除指定的节点  递归
link deleteR(link h,Item item){
	if(h==NULL)return NULL;
	if(key(h->item) == key(item))return h->next;
	h->next = deleteR(h->next,item);
	return h;
}

void STdelete(Item item){
	int i = hash(key(item),M) ;
	heads[i] = deleteR(heads[i],item);
}

void p(link h){
	link t = h;
	while(t!=NULL){
		printf("%c ",key(t->item));
		t = t->next;
	}
	printf("\n");

}
main(){
	STinit(26);
	struct Item item[13] ={'a','s','e','r','c','h','i','n','g','x','m','p','l'};
	int i;
	for(i = 0; i<13;i++)
		STinsert(item[i]);
	for(i = 0; i<M;i++)
		p(heads[i]);
	printf("search: %c \n",key(STsearch('e')));
	struct Item delItem = {'a'};
	STdelete(delItem);
	for(i = 0; i<M;i++)
		p(heads[i]);

}

执行结果

时间: 2024-10-25 18:31:46

散列技术之链地址法(基于无序链表)的相关文章

哈希查找解决地址冲突的两种最常见方法(线性探测再散列,链地址法)C++实现

#include<iostream>#include<iomanip>using namespace std; typedef struct Node{ int data; struct Node *next;}node; int len,num,M,numbers,i=0,mod,count=0;int *a;node **p,*s;float ASL=0,ASL1=0; int ListLength(node * head){ int length=0; node *p; p=

数据结构--散列(分离链接法解决冲突)

散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中.检索时,用同样的方法计算地址,然后到相应的 单元里去取要找的结点.通过散列方法可以对结点进行快速检索.散列(hash,也称"哈希")是一种重要的存储方式,也是一种常见的检索方法. 因此,散列函数更像是一种映射,散列函数的选择有很多种,下面以散列函数为关键值对10取余为例,说明散列的插入关键

散列之分离链接法

1 #include <vector> 2 #include <list> 3 #include <string> 4 #include <algorithm> 5 using std::vector; 6 using std::list; 7 using std::string; 8 using std::find; 9 10 int hash(const string &key) 11 { 12 int hashVal = 0; 13 14 fo

数据结构之散列(开放定址法)

1 // OHash 2 // 关键字:int 3 // Hash函数:hash(X) = X mod TableSize 4 // 冲突解决方法:开放定址法.Index(X, i) = (hash(X) + f(i)) mod TableSize, f(0) = 0 5 // 其中f(i)为: 6 // 1. 线性, f(i) = i 7 // 2. 平方, f(i) = i ^ 2 8 // 3. 双散列, f(i) = i * hash2(X), hash2(X, R) = R - (X

数据结构与算法分析java——散列

1. 散列的概念 散列方法的主要思想是根据结点的关键码值来确定其存储地址:以关键码值K为自变量,通过一定的函数关系h(K)(称为散列函数),计算出对应的函数值来,把这个值解释为结点的存储地址,将结点存入到此存储单元中.检索时,用同样的方法计算地址,然后到相应的单元里去取要找的结点.通过散列方法可以对结点进行快速检索.散列(hash,也称“哈希”)是一种重要的存储方式,也是一种常见的检索方法. 按散列存储方式构造的存储结构称为散列表(hash table).散列表中的一个位置称为槽(slot).散

数据结构与算法之散列

散列 基于数组进行设计的数据结构 优点:可以快速插入,删除和取用数据 缺点:查找操作效率低下 在使用散列表存储数据时,通过一个散列函数将键映射为一个数字,这个数字的范围是0到散列表的长度.理想情况下从key到index应该是一一对应的,然而键的数量可以是无限的,而数组长度是有限的,因此一个更现实的目标是让散列函数尽量均匀地映射到数组中(即让两个或多个key对于1个index,这种现象称为碰撞). 对数组大小常见的限制是: 数组长度应该是一个质数.也会有多种确定数组大小的策略, 所有的策 略都基于

《数据库系统概念》14-静态散列

顺序文件组织的缺点之一是必须通过访问索引或使用二分法搜索来定位数据,这需要较多的I/O操作.基于散列技术的文件组织方式则不需要访问索引结构,散列也提供了一种组织索引的方式.在散列(hash)技术中,用桶(bucket)来表示能存储一条或多条记录的存储单元.如果K代表所有搜索码的集合,B代表所有bucket的集合,则散列函数h表示一个从K到B的映射函数.插入搜索码为Ki的记录时,通过散列函数计算h(Ki)得出bucket的地址,如果这个bucket还有空间,就将数据插入.查询Ki时,也是先通过h(

学习笔记:散列

一.简述 散列是一种数据访问技术,所有的数据项均有散列码与之关联. 散列码可在任何时候通过散列函数计算得到,通常为数据索引. 二.散列构造 ①直接定址法:取关键字本身或其线性函数计算结果作为散列码. ②数字分析法:取关键字中分布较均匀的若干位作为散列码. ③折叠法:根据表长取关键字拆分为若干等长部分后叠加求和并去掉进位的结果作为散列码.(可存在一个不等长部分) ④平方取中法:根据表长取关键字平方数值中间的若干位作为散列码. ⑤除留余数法:根据表长取关键字模运算结果作为散列码. 三.冲突处理 ①开

Hash算法:双重散列

双重散列是线性开型寻址散列(开放寻址法)中的冲突解决技术.双重散列使用在发生冲突时将第二个散列函数应用于键的想法. 此算法使用: (hash1(key) + i * hash2(key)) % TABLE_SIZE  来进行双哈希处理.hash1() 和 hash2() 是哈希函数,而 TABLE_SIZE 是哈希表的大小.当发生碰撞时,我们通过重复增加 步长i 来寻找键. 第一个Hash函数:hash1(key) = key % TABLE_SIZE. 1 /** 2 * 计算首次的Hash值