《数据结构教程(李春葆主编 第五版)》第九章源代码—查找

顺序表基本运算算法(seqlist.cpp)

#include <stdio.h>
#define MAXL 100		//最大长度
typedef int KeyType;	//定义关键字类型为int
typedef char InfoType;

typedef struct
{	KeyType key;		//关键字项
	InfoType data;		//其他数据项,类型为InfoType
} RecType;				//查找元素的类型

void CreateList(RecType R[],KeyType keys[],int n)	//创建顺序表
{
	for (int i=0;i<n;i++)
		R[i].key=keys[i];
}

void DispList(RecType R[],int n)	//输出顺序表
{
	for (int i=0;i<n;i++)
		printf("%d ",R[i].key);
	printf("\n");
}

顺序查找算法

#include "seqlist.cpp"

int SeqSearch(RecType R[],int n,KeyType k)
{
    int i=0;
    while (i<n && R[i].key!=k)	//从表头往后找
		i++;
    if (i>=n) 
		return 0;
    else 
		return i+1;
}

int SeqSearch1(RecType R[],int n,KeyType k)
{
	int i=0;
	R[n].key=k;
	while (R[i].key!=k)	//从表头往后找
		i++;
	if (i==n)				//未找到返回0
		return 0;
	else 
		return i+1;			//找到返回逻辑序号i+1
}

int main()
{
	int n=10;
	RecType R[MAXL];
	KeyType a[]={2,3,1,8,5,4,9,0,7,6},k=9;
	CreateList(R,a,n);
	printf("查找表:"); DispList(R,n);
	printf("R[%d]=%d\n",SeqSearch(R,n,k),k);
	return 1;
}

开放地址法构造的哈希表的运算算法

#include <stdio.h>
#define MaxSize 100			//定义最大哈希表长度
#define NULLKEY -1			//定义空关键字值
#define DELKEY -2			//定义被删关键字值
typedef int KeyType;		//关键字类型
typedef struct
{
	KeyType key;			//关键字域
	int count;				//探测次数域
} HashTable;				//哈希表类型

void InsertHT(HashTable ha[],int &n,int m,int p,KeyType k)  //将关键字k插入到哈希表中
{
	int i,adr;
	adr=k % p;					//计算哈希函数值
	if (ha[adr].key==NULLKEY || ha[adr].key==DELKEY)//k可以直接放在哈希表中
	{
		ha[adr].key=k;
		ha[adr].count=1;
	}
	else						//发生冲突时采用线性探测法解决冲突
	{
		i=1;					//i记录k发生冲突的次数
		do 
		{
			adr=(adr+1) % m;	//线性探测
			i++;
		} while (ha[adr].key!=NULLKEY && ha[adr].key!=DELKEY);
		ha[adr].key=k;			//在adr处放置k
		ha[adr].count=i;		//设置探测次数
	}
	n++;						//总关键字个数增1
	
}

void CreateHT(HashTable ha[],int &n,int m,int p,KeyType keys[],int n1)  //创建哈希表
{
	for (int i=0;i<m;i++)				//哈希表置空的初值
    {
        ha[i].key=NULLKEY;
	    ha[i].count=0;
    }
	n=0;
	for (i=0;i<n1;i++)
		InsertHT(ha,n,m,p,keys[i]);	//插入n个关键字
}

void SearchHT(HashTable ha[],int m,int p,KeyType k)  //在哈希表中查找关键字k
{
	int i=1,adr;
	adr=k % p;					//计算哈希函数值
	while (ha[adr].key!=NULLKEY && ha[adr].key!=k)
	{
		i++;					//累计关键字比较次数
		adr=(adr+1) % m;		//线性探测
	}
	if (ha[adr].key==k)			//查找成功
		printf("成功:关键字%d,比较%d次\n",k,i);
	else						//查找失败
		printf("失败:关键字%d,比较%d次\n",k,i);
}

bool DeleteHT(HashTable ha[],int &n,int m,int p,KeyType k)	//删除哈希表中关键字k
{
	int adr;
	adr=k % p;					//计算哈希函数值
	while (ha[adr].key!=NULLKEY && ha[adr].key!=k)
		adr=(adr+1) % m;		//线性探测
	if (ha[adr].key==k)			//查找成功
	{
		ha[adr].key=DELKEY;		//删除关键字k
		return true;
	}
	else						//查找失败
		return false;			//返回假
}

void ASL(HashTable ha[],int n,int m,int p)	//求平均查找长度
{
	int i,j;
	int succ=0,unsucc=0,s;
	for (i=0;i<m;i++)
		if (ha[i].key!=NULLKEY)
			succ+=ha[i].count;		//累计成功时总关键字比较次数
	printf(" 成功情况下ASL(%d)=%g\n",n,succ*1.0/n);
	for (i=0;i<p;i++)
	{
		s=1; j=i;
		while (ha[j].key!=NULLKEY)
		{
			s++;
			j=(j+1) % m;
		}
		unsucc+=s;
	}
	printf(" 不成功情况下ASL(%d)=%g\n",n,unsucc*1.0/p);
}

void DispHT(HashTable ha[],int n,int m,int p)  //输出哈希表
{
	int i,j;
	int succ=0,unsucc=0,s;
	printf("哈希表:\n");
	printf(" 哈希表地址:\t");
	for (i=0;i<m;i++) 
		printf(" %3d",i);
	printf(" \n");
    printf(" 哈希表关键字:\t");
	for (i=0;i<m;i++) 
		if (ha[i].key==NULLKEY)
			printf("    ");			//输出3个空格
		else
			printf(" %3d",ha[i].key);
	printf(" \n");
	printf(" 探测次数:\t");
	for (i=0;i<m;i++)
		if (ha[i].key==NULLKEY)
			printf("    ");			//输出3个空格
		else
			printf(" %3d",ha[i].count);
	printf(" \n");
	ASL(ha,n,m,p);
}

int main()
{
	int keys[]={16,74,60,43,54,90,46,31,29,88,77};
	int n,m=13,p=13,k;
	HashTable ha[MaxSize];
	printf("(1)创建哈希表\n"); CreateHT(ha,n,m,p,keys,11);
	printf("(2)显示哈希表:\n"); DispHT(ha,n,m,p);
	k=29;
	printf("(3)查找"); SearchHT(ha,m,p,k);
	k=31;
	printf("(4)删除:关键字%d\n",k);
	DeleteHT(ha,n,m,p,k);
	printf("(5)显示哈希表:\n"); DispHT(ha,n,m,p);
	printf("(6)查找"); SearchHT(ha,m,p,k);
	printf("(7)插入:关键字%d\n",k);
	InsertHT(ha,n,m,p,k);
	printf("(8)显示哈希表:\n"); DispHT(ha,n,m,p);
	printf("\n");
	return 1;
}

拉链法构造的哈希表的运算算法

#include <stdio.h>
#include <malloc.h>
#define MaxSize 100				//定义最大哈希表长度
typedef int KeyType;			//关键字类型
typedef struct node
{
	KeyType key;				//关键字域
	struct node *next;			//下一个结点指针
} NodeType;						//单链表结点类型
typedef struct
{
	NodeType *firstp;			//首结点指针
} HashTable;					//哈希表类型

void InsertHT(HashTable ha[],int &n,int p,KeyType k)  //将关键字k插入到哈希表中
{
	int adr;
	adr=k % p;					//计算哈希函数值
	NodeType *q;
	q=(NodeType *)malloc(sizeof(NodeType));
	q->key=k;					//创建一个结点q,存放关键字k
	q->next=NULL;
	if (ha[adr].firstp==NULL)	//若单链表adr为空
		ha[adr].firstp=q;
	else						//若单链表adr不空
	{
		q->next=ha[adr].firstp;	//采用头插法插入到ha[adr]的单链表中
		ha[adr].firstp=q;
	}
	n++;						//结点总个数增1
}

void CreateHT(HashTable ha[],int &n,int m,int p,KeyType keys[],int n1)  //创建哈希表
{
	for (int i=0;i<m;i++)			//哈希表置初值
		ha[i].firstp=NULL;
	n=0;
	for (i=0;i<n1;i++)
		InsertHT(ha,n,p,keys[i]);//插入n个关键字
}

void SearchHT(HashTable ha[],int p,KeyType k)	//在哈希表中查找关键字k
{
	int i=0,adr;
	adr=k % p;					//计算哈希函数值
	NodeType *q;
	q=ha[adr].firstp;			//q指向对应单链表的首结点
	while (q!=NULL)				//扫描单链表adr的所有结点
	{
		i++;
		if (q->key==k)			//查找成功
			break;				//退出循环
		q=q->next;
	}
	if (q!=NULL)				//查找成功
		printf("成功:关键字%d,比较%d次\n",k,i);
	else						//查找失败
		printf("失败:关键字%d,比较%d次\n",k,i);
}

bool DeleteHT(HashTable ha[],int &n,int m,int p,KeyType k)	//删除哈希表中关键字k
{
	int adr;
	adr=k % p;					//计算哈希函数值
	NodeType *q,*preq;
	q=ha[adr].firstp;			//q指向对应单链表的首结点
	if (q==NULL) 
		return false;			//对应单链表为空
	if (q->key==k)				//首结点为k
	{
		ha[adr].firstp=q->next;//删除结点q
		free(q);
		n--;					//结点总个数减1
		return true;			//返回真
	}
	preq=q; q=q->next;			//首结点不为k时
	while (q!=NULL)
	{
		if (q->key==k)			//查找成功
			break;				//退出循环
		q=q->next;
	}
	if (q!=NULL)				//查找成功
	{
		preq->next=q->next;		//删除结点q
		free(q);
		n--;					//结点总个数减1
		return true;			//返回真
	}
	else return false;			//未找到k,返回假
}

void ASL(HashTable ha[],int n,int m)	//求平均查找长度
{
	int succ=0,unsucc=0,s;
	NodeType *q;
	for (int i=0;i<m;i++)		//扫描所有哈希表地址空间
	{
		s=0;
		q=ha[i].firstp;			//q指向单链表i的首结点
		while (q!=NULL)			//扫描单链表i的所有结点
		{
			q=q->next;
			s++;				//s记录当前结点是对应单链表的第几个结点
			succ+=s;			//累计成功的总比较次数
		}
		unsucc+=s;				//累计不成功的总比较次数
	}
	printf(" 成功情况下ASL(%d)=%g\n",n,succ*1.0/n);
	printf(" 不成功情况下ASL(%d)=%g\n",n,unsucc*1.0/m);
}

void DispHT(HashTable ha[],int n,int m)  //输出哈希表
{
	int succ=0,unsucc=0,s;
	NodeType *q;
	for (int i=0;i<m;i++)		//扫描所有哈希表地址空间
	{
		s=0;
		printf(" %3d:\t",i);
		q=ha[i].firstp;			//q指向单链表i的首结点
		while (q!=NULL)			//扫描单链表i的所有结点
		{
			printf("%4d",q->key);
			q=q->next;
			s++;				//s记录当前结点是对应单链表的第几个结点
			succ+=s;			//累计成功的总比较次数
		}
		unsucc+=s;				//累计不成功的总比较次数
		printf("\n");
	}
	printf(" 成功情况下ASL(%d)=%g\n",n,succ*1.0/n);
	printf(" 不成功情况下ASL(%d)=%g\n",n,unsucc*1.0/m);
}

void DestroyHT(HashTable ha[],int m)	//销毁哈希表
{
	int i;
	NodeType *q,*preq;
	for (i=0;i<m;i++)
	{
		q=ha[i].firstp;			//q指向单链表i的首结点
		while (q!=NULL)			//扫描单链表i的所有结点
		{
			preq=q; q=q->next;
			free(preq);
		}
	}
}

int main()
{
	int keys[]={16,74,60,43,54,90,46,31,29,88,77};
	int n,m=13,p=13,k=29;
	HashTable ha[MaxSize];
	printf("(1)创建哈希表\n"); CreateHT(ha,n,m,p,keys,11);
	printf("(2)显示哈希表:\n"); DispHT(ha,n,m);
	printf("(3)查找"); SearchHT(ha,p,k);
	k=77;
	printf("(4)删除:关键字%d\n",k);
	DeleteHT(ha,n,m,p,k);
	printf("(5)显示哈希表:\n"); DispHT(ha,n,m);
	printf("(6)查找"); SearchHT(ha,p,k);
	printf("(7)插入:关键字%d\n",k);
	InsertHT(ha,n,p,k);
	printf("(8)显示哈希表:\n"); DispHT(ha,n,m);
	printf("\n");
	DestroyHT(ha, m);		//销毁哈希表
	return 1;
}
  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
数据结构教程》是李春葆撰写的一本经典教材,这里提到的第三是其更新后的本。这本教材是计算机科学和软件工程专业的学生必备的参考书之一。 这本教程数据结构作为核心内容,系统而全面地介绍了各种数据结构及其应用。其中包括线性表、栈、队列、树、图等常见的数据结构以及它们的操作和实现方式。每个章节都有详细而清晰的讲解,配有大量的示例和习题,有助于读者理解和掌握各种数据结构的基本知识和算。 教材的第三相比前两进行了全面的更新和改进。在保留经典内容的基础上,增加了一些新的数据结构和算的讲解,如红黑树、哈希表、最短路径算等。并且,教材还增加了一些实际应用的案例分析,如文件系统、数据库管理系统等,让读者更好地理解数据结构在实际应用中的作用和意义。 这本教程深入浅出,适合初学者和有一定编程基础的读者阅读。它不仅给出了数据结构的原理和概念,更重要的是通过丰富的例子和习题培养了读者的实际操作和问题解决能力。同时,教材还提供了配套的源代码实验指导,供读者进一步学习和实践。 总之,《数据结构教程李春葆第三是一本值得推荐的编程教材。无论是学生还是从事计算机相关工作的专业人士,阅读并掌握其中的知识都将对他们的编程能力和问题解决能力有所提升。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值