部分查找算法的对比实现

部分查找算法的对比实现

通过num变量改变数据集的规模,来进行对比。

顺序查找

#include <stdio.h>
#include<stdlib.h>
#include<time.h>
#include<sys/timeb.h>
typedef int KeyType;
typedef struct {//顺序表结构类型定义
	KeyType *R;//表基址
	int length;//表长
}SSTable;

int Search_Seq( SSTable ST , KeyType key ){
	int i;
	ST.R[0] =key;
	for( i=ST.length-1; ST.R[i] != key; --i );
	return i;
}

int * getRand(int *t,int num){
	int *a = (int*)malloc(sizeof(int)*num);
	int i;
	int temp;
	srand(time(NULL));
	for(i = 0;i<num;i++){
		temp = rand()%(num+1);
		if(i == num/2)
			*t = temp; 
		a[i] = temp;
	}
	return a;
}

long getTime()
{
    struct timeb tb;
    ftime(&tb);
    //前面是毫秒,后面是微秒
    return tb.time*1000+tb.millitm;
}

int main(){
	int find;
	int num = 1000000;
	SSTable s1;
	s1.R = getRand(&find,num);
	s1.length = num;
	long t3 = getTime();
	int result1 = Search_Seq(s1,find);
	long t4 = getTime();
	printf("顺序查找(%d):找到了%d,在下标:%d处,耗时:%ldms",num,find,result1,t4-t3);
	return 0;
}

折半查找

#include <stdlib.h>
#include <stdio.h>
#include<time.h>
#include<sys/timeb.h>
typedef int KeyType;
typedef struct {//顺序表结构类型定义
	KeyType *R;//表基址
	int length;//表长
}SSTable;

int Search_Bin (SSTable ST,KeyType key ) {
	int low = 1;
	int high = ST.length;//置区间初值
    int mid;
	while (low <= high) {
		mid = (low + high)/ 2;
		if (ST.R[mid] == key) 
			return mid;//找到待查元素
		else if (key < ST.R[mid])//缩小查找区间
			high=mid-1;//继续在前半区间进行查找
		else
			low = mid + 1;//继续在后半区间进行查找
	}
	return 0;//顺序表中不存在待查元素
}

int * getNumber(int *t,int num){
	int *a = (int*)malloc(sizeof(int)*num);
	int i;
	int temp;
	a[0] = 0;
	srand(time(NULL));
	for(i = 1;i<num;i++){
		int temp = rand()%(num+1); 
		if(i == num/2)
			*t =i + temp;//递增的 
		a[i] = i + temp;
	}
	return a;
}

long getTime()
{
    struct timeb tb;
    ftime(&tb);
    //前面是毫秒,后面是微秒
    return tb.time*1000+tb.millitm;
}

int main(){
	int find;
	int num = 1000000;
	SSTable s2;
	s2.R = getNumber(&find,num);
	s2.length = num;
	long t5 = getTime();
	int result2 = Search_Bin(s2,find);
	long t6 = getTime();
	printf("折半查找(%d):找到了%d,在下标:%d,耗时:%dms",num,find,result2,t6-t5);
	return 0;
}

二叉排序树

#include<stdio.h> 
#include<stdlib.h>
#include<time.h>
#include<sys/timeb.h>
typedef int KeyType;            //定义关键字类型
typedef struct node                   //记录类型
{    
    KeyType key;                      //关键字项
    struct node *lchild,*rchild;    //左右孩子指针
} BSTNode;

BSTNode *CreatBST(KeyType A[],int n);    //顺序读入数组A中的关键字, 依序建立一棵二叉排序树并返回根结点指针。由裁判程序实现,细节不表。
int SearchBST(BSTNode *bt,KeyType k);   //在函数中输出从根节点出发进行查找的节点路径 ,如果找到k,返回1,否则返回0。
int * getRand(int *t,int num);
long getTime();

int main()
{
	int num = 100;
    BSTNode *bt = NULL;
    int find;
	int *arr = getRand(&find,num);
	bt = CreatBST(arr,num);
	long t1 = getTime();
	if(SearchBST(bt,find))
	printf("二叉排序树查找(%d)找到了%d,",num,find);
	long t2 = getTime();
	printf("耗时:%dms",t2-t1);
    return 0;
}

// 补充裁判程序未给出函数 

int * getRand(int *t,int num){
	int *a = (int*)malloc(sizeof(int)*num);
	int i;
	int temp;
	srand(time(NULL));
	for(i = 0;i<num;i++){
		int temp = rand()%(num+1);
		if(i == num/2)
			*t = temp; 
		a[i] = temp;
	}
	return a;
}

BSTNode * InitBST(KeyType e){
	BSTNode *BT;
	BT = (BSTNode *)malloc(sizeof(BSTNode));
	if(!BT){
		return NULL;
	}
	BT->key = e;
	BT->lchild = BT->rchild =NULL;
	return BT;
}


// 此处左小于根小于右 
void InsertBST(BSTNode * BT, KeyType e){
	
	BSTNode *T;	
	T = BT;
	while(T){
		// 寻找插入位置,并插入 
		if(T->key == e){
			return ;
		} 
		
		if(T->key < e){
			// 右孩子存在,则继续寻找 
			if(T->rchild){
				T = T->rchild;
				continue;	
			}
			// 不存在则进行插入
			T->rchild = (BSTNode *)malloc(sizeof(BSTNode));
			T->rchild->key = e;
			T->rchild->lchild = T->rchild->rchild =NULL;
			return ;
		}else if(T->key > e){
			// 右孩子存在,则继续寻找 
			if(T->lchild){
				T = T->lchild;
				continue;	
			}
			// 不存在则进行插入
			T->lchild = (BSTNode *)malloc(sizeof(BSTNode));
			T->lchild->key = e;
			T->lchild->lchild = T->lchild->rchild =NULL;
		}
		
	}
	
	
}

BSTNode *CreatBST(KeyType A[],int n){
	BSTNode *BT;
	int i;
	BT = InitBST(A[0]);
	for(i=1;i<n;i++){
		InsertBST(BT, A[i]);
	}
	return BT;	
}

long getTime()
{
    struct timeb tb;
    ftime(&tb);
    //前面是毫秒,后面是微秒
    return tb.time*1000+tb.millitm;
}

int SearchBST(BSTNode *bt,KeyType k){
	// 定义 
	BSTNode *t;
	t = bt;	
	while(t){
		// 依次输出查找时的值 
		//printf("%d ",t->key);
		// 如果相等则返回找到 
		if(t->key==k){
			return 1;
		}else if(t->key<k){
			// 小于根结点则向左孩子寻找 
			t = t->rchild;
		}else{
			// 大于根结点则向右孩子寻找
			t = t->lchild;
		}
	}
	return 0;
}  

散列表

使用的是线性探测法处理冲突,你们可以自己改一改改成拉链法。

#include <stdio.h>
#include <stdlib.h>
#include<time.h>
#include<sys/timeb.h>
typedef int ElementType;     /* 关键词类型用整型 */
typedef int Index;           /* 散列地址类型 */
typedef Index Position;      /* 数据所在位置与散列地址是同一类型 */
/* 散列单元状态类型,分别对应:有合法元素、空单元、有已删除元素 */
typedef enum { Legitimate, Empty, Deleted } EntryType;

typedef struct HashEntry Cell; /* 散列表单元类型 */
struct HashEntry{
    ElementType Data; /* 存放元素 */
    EntryType Info;   /* 单元状态 */
};

typedef struct TblNode *HashTable; /* 散列表类型 */
struct TblNode {   /* 散列表结点定义 */
    int TableSize; /* 表的最大长度 */
    Cell *Cells;   /* 存放散列单元数据的数组 */
};

HashTable BuildTable(int *find,int num,int tablelen); /* 裁判实现,细节不表 */
Position Hash( ElementType Key, int TableSize )
{
    return (Key % TableSize);
}

long getTime()
{
    struct timeb tb;
    ftime(&tb);
    //前面是毫秒,后面是微秒
    return tb.time*1000+tb.millitm;
}

#define ERROR -1
Position Find( HashTable H, ElementType Key );

int main()
{
    HashTable H;
    int num = 1000000;
    int len = 1000000;
    int find;
    Position P;
    H = BuildTable(&find,num,len);
	long t1 = getTime(); 
    P = Find(H, find);
    long t2 = getTime();
    if (P==ERROR)
        printf("ERROR: %d is not found and the table is full,use %ldms\n", find,t2-t1);
    else if (H->Cells[P].Info == Legitimate)
        printf("散列表(%d)%d is at position %d,use %ldms\n",num, find, P,t2-t1);
    else
        printf("%d is not found.  Position %d is returned,use %ldms\n", find, P,t2-t1);
        
    return 0;
}

/* 你的代码将被嵌在这里 */
Position Find( HashTable H, ElementType Key ){
	int maxsize = H->TableSize;
	int d = 0;//增量序列 
	Position p = Hash(Key,H->TableSize);
	while(1){
		if(H->Cells[p].Info == Empty || H->Cells[p].Data == Key){
			return p;
		}
		if(d < maxsize-1){
			d++;
		}else{
            break;
        }
		p = (Hash(Key,H->TableSize)+d)%maxsize;
	}
	return ERROR;
}

HashTable BuildTable(int *find,int num,int tablelen){
	HashTable t = (HashTable)malloc(sizeof(TblNode));//初始化 
	t->Cells = (Cell*)malloc(sizeof(Cell)*tablelen);
	t->TableSize = tablelen;
	srand(time(NULL));
	int temp;
	int flag = 1;//判断又没有找到位置 
	for(int i = 0;i < num;i++)
		t->Cells[i].Info = Empty;//初始化状态 
	for(int i = 0;i < num;i++){
		temp = rand()%(num+1);
		int p = Hash(temp,num);
		if(i == (num-1)/2)
			*find = temp;
		while(t->Cells[p].Info == Legitimate){//处理冲突 
			int d = 0;
			if(d < num-1){
			d++;
			}else{
				flag = 0;
            	break;
        	}
			p = (Hash(p,t->TableSize)+d)%t->TableSize;
		}
		if(flag){
			t->Cells[p].Data = temp;
			t->Cells[p].Info = Legitimate;
		} 
	}
	return t;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值