数据结构--C语言--查找算法的实现--顺序表的查找

1.实验目的

熟练掌握顺序表和有序表的查找方法,掌握其时间复杂度的分析方法

2.实验内容

(1)验证并设计顺序表的查找(顺序查找、折半查找)算法

(2)验证二叉排序树上的查找(创建、查找、插入)算法

(3)验证Hash表查找(Hash函数定义、建立,查找,插入)算法

//顺序表的顺序查找 折半查找 二叉排序树 以数值型关键字为例 
#include<stdio.h>
#include<stdlib.h>
#define MAXSIZE 100
#define INCRESIZE 20
#define EQ(a,b) a==b
#define LT(a,b) a<b
#define LQ(a,b) a<=b
#define ERROR 0
#define FALSE 0
#define TRUE 1 
#define OK 1

typedef int ElemType;
typedef int KeyType;
typedef int Status;

typedef struct{
	ElemType *base;
	int length;//表长度 0号单元不存储内容 
}SSTable;

typedef struct BTNode{
	ElemType data;
	struct BTNode *lchild;
	struct BTNode *rchild;
}BTNode,*BiTree;

Status Init_Seq(SSTable &ST){
	ST.base = (ElemType *)malloc(MAXSIZE*sizeof(ElemType));
	if(!ST.base) return ERROR;
	ST.length = 0;
	return OK;
}

Status Creat_Seq(SSTable &ST){
	int count = 1;
	printf("\n构造顺序表,输入-111意为停止输入\n");
	scanf("%d",ST.base+count);
	while(ST.base[count]!=-111){
		count++;
		if(count>MAXSIZE){
			ST.base = (ElemType *)realloc(ST.base,(MAXSIZE+INCRESIZE)*sizeof(ElemType));
			if(!ST.base) return ERROR;
		}
		scanf("%d",ST.base+count);
	}
	ST.length = --count;
	return OK;
}

int Search_Seq(SSTable ST,KeyType key){//0号单元设哨兵 
	ST.base[0] = key;
	int i;
	for(i=ST.length;*(ST.base+i)!=key;i--) ;//空语句 
	return i;
}

Status Sort(SSTable &ST){
	int min,temp;
	for(int i=1;i<=ST.length;i++){
		min = i;
		for(int j=i;j<=ST.length;j++){
			if(ST.base[min]>ST.base[j]) min = j;
		}
		temp = ST.base[min];
		ST.base[min] = ST.base[i];
		ST.base[i] = temp;
	}
	printf("\n\n排序后的序列为:");
	for(int i=1;i<=ST.length;i++) printf("%d  ",ST.base[i]);
}

int Search_Bin(SSTable ST,KeyType key){
	int low=1,high=ST.length,mid;
	Sort(ST);
	while(low<=high){
		mid = (low+high)/2;
		if(EQ(key,ST.base[mid])) return mid;
		else if(LT(key,ST.base[mid])) high = mid-1;
		else low = mid+1;
	}
	return 0;
}

Status SearchBST(BiTree T,KeyType key,BiTree f,BiTree &p){//查找成功p为数据所在结点指针 否则是插入位置指针 f是工作指针 始终指向当前查找结点的父母 
	if(!T){
		p = f;//直接插入在根结点 
		return FALSE;//查找失败 
	}else if(EQ(key,T->data)){
		p = T;
		return TRUE;//查找成功 
	}else if(LT(key,T->data)){
		return SearchBST(T->lchild,key,T,p);//在左子树中继续查找 
	}else{
		return SearchBST(T->rchild,key,T,p);//在右子树中继续查找 
	} 
}

Status InsertBST(BiTree &T,ElemType e){
	BiTree p;
	if(!SearchBST(T,e,NULL,p)){//如果是空树的话p返回NULL 不是空树的话f在SearchBST()里会做改变 最后查找失败时p=f是不为空的 
		BiTree s = (BiTree)malloc(sizeof(BTNode));
		s->data = e; s->lchild = s->rchild = NULL;
		if(!p) T=s;//空树 
		else if(p->data>e) p->lchild = s;//已经查找到了叶子结点处 
		else p->rchild = s;
		return TRUE;
	}
	return FALSE; 
}

Status CreatBST(BiTree &T){
	printf("\n\n建立一棵二叉排序树,输入-111意为停止\n");
	ElemType e;
	scanf("%d",&e);
	while(e!=-111){
		InsertBST(T,e);
		scanf("%d",&e);
	}
	return OK;
}

int main(){
	SSTable ST;
	KeyType key;
	BiTree T=NULL,p=NULL;
	int locate;
	
	Init_Seq(ST);
	Creat_Seq(ST);
	printf("\n\n请输入待查找的数:");
	scanf("%d",&key);
	
	if(Search_Seq(ST,key)) printf("\n\n顺序查找结果:%d在顺序表中的第%d位\n",key,Search_Seq(ST,key));
	else printf("\n顺序查找失败 该数据不存在!\n");
	
	locate = Search_Bin(ST,key);
	if(locate) printf("\n折半查找结果:%d在有序表中的第%d位\n",key,locate);
	else printf("\n\n折半查找失败 该数据不存在!\n");
	
	
	CreatBST(T);
	printf("\n请输入待查找的数:");
	scanf("%d",&key);
	SearchBST(T,key,NULL,p);
	if(SearchBST(T,key,NULL,p)) printf("查找成功!\n");
	else printf("查找失败!\n");
} 
//哈希表的定义 创建 查找 插入 以数值型元素为例 
#include<stdio.h>
#include<stdlib.h>

#define EQ(a,b) a==b
#define LT(a,b) a<b
#define LQ(a,b) a<=b
#define MAXSIZE 40
#define INCRESIZE 10
#define SUCCESS 1
#define UNSUCCESS 0
#define DUPLICATE -1
#define NULLKEY -111

typedef int KeyType;
typedef int Status;
typedef int ElemType;

typedef struct{
	ElemType *base;//数据元素存储基址 动态分配数组 
	int count;//当前数据元素的个数 
	int sizeindex;//hashsize[sizeindex]为当前容量 
}HashTable;

//初始化 
Status InitHash(HashTable &H){
	H.base = (ElemType *)malloc(MAXSIZE*sizeof(ElemType));
	if(!H.base) exit(DUPLICATE);
	H.sizeindex = MAXSIZE;
	H.count = 0;
	for(int i=0;i<H.sizeindex;i++) H.base[i] = NULLKEY;  
	return SUCCESS;
}

//构造哈希函数 
Status Hash(ElemType e,int &p){//根据函数计算存储位置并赋给p
	p =  e%19;//除留余数法和平方取中法结合构造哈希函数
	return SUCCESS;
}

Status collision(HashTable H,int &p){//线性探测再散列表 
	int i;
	for(i=p+1;i<H.sizeindex;i++)
		if(H.base[i]==NULLKEY) p=i;
	if(i==H.sizeindex){
		H.base = (ElemType *)realloc(H.base,(H.sizeindex+INCRESIZE)*sizeof(ElemType));
		if(!H.base) exit(DUPLICATE);
		H.sizeindex += INCRESIZE;
		p = H.sizeindex;
	}
	return SUCCESS;
}

//在哈希表里查找key 如果查找成功 p存储在表中的下标 返回成功 否则p指示插入位置 返回不成功,c用来计算冲突个数 
Status SearchHash(HashTable H,KeyType key,int &p,int &c){
	Hash(key,p);//用公式来计算他在数组里的下标
	
	//当该位置中填有记录 并且与所查找的关键字不相等的时候
	while(H.base[p]!=NULLKEY&&H.base[p]!=key) {
		collision(H,p);//求得下一探测地址
	} 
		
		
	if(EQ(H.base[p],key)) return SUCCESS;
	return UNSUCCESS;//NULLKEY 	
}

//插入
Status InsertHash(HashTable &H,ElemType e){
	int p,c=0;//c初始值为0在建表的时候可以用作参考 
	if(SearchHash(H,e,p,c)){
		return UNSUCCESS;	
	}
	else{
		H.base[p] = e;
		H.count++;
		return SUCCESS;
	}
}

Status CreatHash(HashTable &H){
	InitHash(H);
	ElemType a;
	printf("请构造哈希表 输入-111意为停止:\n");
	scanf("%d",&a);
	while(a!=-111){
		if(!InsertHash(H,a)) printf("已存在该关键字!\n");
		scanf("%d ",&a);
	}
	return SUCCESS;
}

void Visitall(HashTable H){
	int num = H.count;
	printf("\nresult:");
	for(int i=0;i<H.sizeindex,num!=0;i++){
		if(H.base[i]!=NULLKEY){
			printf("%d ",H.base[i]);
			num--;
		} 
	}
} 

int main(){
	ElemType num;
	int p,c;
	HashTable H;
	CreatHash(H);
	
	Visitall(H);
	printf("\n请输入你要查找的关键字:");
	scanf("%d",&num);
	if(SearchHash(H,num,p,c)) printf("\n查找成功!\n");
	else printf("\n查找失败!\n");
	
	return 0;
}

猜你喜欢

转载自blog.csdn.net/J_SUNV/article/details/85229847