大二下小学期《数据结构》课程设计报告1

题目一: 基本查找算法比较
1) 对以下 3 种基本的查找算法的性能进行比较:顺序查找,二叉查找树,哈希。算法
包含两步:第一步:从文件中读取数据建查找表;第二步从文件中读取查找关键字
静态查找。
2) 待查找记录的个数不小于 n ( n<=1000000),关键字key 互不相同,取值范围0-109;
查询操作的次数为m(m=100000),每次查询的关键字随机生成,取值范围0-109.
3) 比较的指标为关键字的比较次数(包含建立查找表和查找操作)、内存空间和实际
运行时间。至少用5 组不同的数据作比较,至少包含完全正序(n=10000)、完全逆
序(n=10000)及随机(n=10000、100000,1000000)情况。
4) 为提高比较的可信度,待查找数据和查询关键字数据的生成及排序等预处理要设计
成一个独立功能,并将结果数据保留在data.in 文件中,格式如下:第1 行,用空
格分隔的两个非负整数,分别表示n 和m;接下来的n 行,每行一个非负整数,表
示待查询数据;接下来的m 行,每行一个非负整数,表示查询的关键字。
5) 每次查询都输出到结果文件 data.out 中,一共m 行。每行包含对应的查询关键字的
查询结果。查询结果:成功输出“Yes”, 不成功输出“No”。
6) 哈希的散列函数建议使用 key mod P,P 是大于n 的质数,注意内存限制;冲突
消解建议使用简单的线性探查法。当然,有能力的同学可以自己设计哈希函数,使
用统计结果较好的冲突消解方法,如平方探测法。

7) 对结果作简单分析,包括对各组数据得出结果波动大小的解释。



我的解答:

由题目分析得,设计2个程序,其中一个来产生随机数据和key,另外一个程序用来进行对数据的分析。由于rand()函数只能产生0~32767之间的随机数,但是题目要求随机数的范围会很大,怎么才能生成很大的随机数,又不破坏均匀性?我采用的方法是按位随机,每次产生0~9之间的随机数,做为9位数的其中一位,然后生成9次,组合起来就是一个9位的随机数。

对于线性分析,在全局定义一个很大的数组,每次程序将数据读入到数组中,用一个2重循环进行分析。对于二叉树查找,首先构造二叉排序树,然后在对每个key进行查找。对于哈希算法,我才用拉链法,取质数10007进行哈希。

如何得到每种方法的比较次数?我才用设置全局量(long long ),在3种方法的查询函数中,在有比较的时候,全局量自加一,然后在屏幕上输出程序运行完成后的各个次数,对其进行分析。

//============================================================================
// Name        : creat_rand.cpp
// Author      : menglei
// Version     : 2013.8.13  20:19
// Copyright   : Your copyright notice
// Description : 此程序产生5组随机的数据
//============================================================================

#include 
#include 
using namespace std;


int min_rand(){
	//返回一个0到9的随机数

	//srand((unsigned)time(NULL));
	return rand()%10;
}
int myRand(int bit){
	//hit表示多少位,返回一个在int范围内bit位的一个随机数
	int randdata = 0;
	while(bit--){
		randdata = 10*randdata +min_rand();
	}
	return randdata;
}

int main() {
	/*如何产生一个很大范围的随机数?
	 *采用按位结合法和丢弃法结合
	 *每位随机0到9,---按位结合
	 超过范围的数字就丢弃掉----丢弃法
	*/
	ofstream fout1("data1_in.txt");
	fout1<<"10000"<<" "<<"100000"<0;i--){
		fout2<


//============================================================================
// Name        : temp1.cpp
// Author      : menglei
// Version     :
// Copyright   : Your copyright notice
// Description : 数据的分析
//============================================================================
#include 
#include 
#include 
using namespace std;

class node{
public:
	node(int value):value(value),left(NULL),right(NULL){};//构造函数
	node(){right = NULL;left =NULL;value = -1;}
	node*getleft(){return left;}
	node*getright(){return right;}
	int getvalue(){return value;}
	void setvalue(int t){value = t;}
	void setleft(node * l){left = l;}
	void setright(node * r){right = r;}
	node *right;
	node *left;
	int value;
};

class searchTree{
public:
	searchTree(int i){init(i);}
	void init(int);
	void deleteTree(node*);
	void insert (node * ,int);
	bool find(node *,int,long long & );
	node getRoot(){return root;}
	void midOder(node *);

private:
	node root;
};

void searchTree::init(int a){
	root.left = NULL;
	root.right = NULL;
	root.value = a;
}
void searchTree::deleteTree(node * a){
	if(a != NULL){
		deleteTree(a->getleft());
		deleteTree(a->getright());
		delete a;
	}
}
void searchTree::insert(node *n,int i){
	node * pointer = NULL;
	if(n == NULL){init(i);return ;}
	else pointer = n;
	while(1){
		if(pointer->getvalue() == i) return ;//要插入的节点value和根节点的value相同则返回
		else if(pointer->getvalue() >i){
			if(pointer->getleft() == NULL){ //左侧无节点了,插入
				pointer->left = new node(i);
				return ;
			}else
				pointer = pointer->left;
		}
		else
		{
			if(pointer->getright() == NULL){
				pointer->right = new node(i);
				return;
			}else
				pointer = pointer->right;
		}
	}
}
void searchTree::midOder(node *t){
	if(t != NULL){

		midOder(t->getleft());
		cout<getvalue()<<" ";
		midOder(t->getright());
	}
}
bool searchTree::find(node *t,int v,long long &y){
	//find node value equal to 'v' in tree whose root named 't'

	if(t == NULL){y++;return false; }
	if(t->getvalue() == v){y++; return true;}
	if(t->getvalue() > v){
		y++;
		return find(t->left,v,y);}
	if(t->getvalue() < v){
		y++;
		return find(t->right, v,y);}
}

int data_array[1000001];   //all scorp
long long x,y,z;//x表示顺序查找次数,y表示二叉树,z表示哈希法
void shunxu(){
		int n,m;   int t;
		ifstream fin3("data_in.txt");
		ofstream fout3("shunxu_out.txt");
		fin3>>n>>m;
		cout<<"n和m的值分别为:"<>data_array[i];
		}
		//顺序查找,m*n   all "NO" ?
		bool flag = false;
		for(int i=0;i>t;
			for(int j=0;j>n>>m;
		cout<<"n和m的值分别为:"<>t;
			tree.insert(tempNode,t);
		}
		bool flag;
		for(int i=0;i>t;
			flag = tree.find(tempNode,t,y);
			if(flag)
				fout3<<"YES"<>n>>m;
	cout<<"n和m的值分别为:"<>t;
		haxi = t % 10007;     //10007,为比10000大的质数
		temp_cnode = new cnode(t);
		t_cnode = nodearray[haxi].next;
		nodearray[haxi].next = temp_cnode;
		temp_cnode->next = t_cnode;
	}
	for(int i=0;i>t;
		haxi = t % 10007;
		temp_cnode = nodearray[haxi].next;
		while(temp_cnode != NULL){
			z = z + 1;
			if(temp_cnode->value == t){
				flag = true;

				break;}
			temp_cnode = temp_cnode->next;
		}
		if(flag)
			fout3<<"YES"<



测试结果:

第一组:(正序)

顺序查找所需时间为:10

二叉排序树查找时间为:4

哈希表法所用查找时间为:1

3种方法的比较次数分别为:

999998882  847624131  99917

第二组:(逆序)

顺序查找所需时间为:9

二叉排序树查找时间为:3

哈希表法所用查找时间为:1

3种方法的比较次数分别为:

999995463  264858  99926

第三组:(随机10000)

顺序查找所需时间为:9

二叉排序树查找时间为:2

哈希表法所用查找时间为:1

3种方法的比较次数分别为:

999985668  1741928  100014

第四组:(随机100000)

顺序查找所需时间为:82

二叉排序树查找时间为:2

哈希表法所用查找时间为:1

3种方法的比较次数分别为:

9999602349  2324639  998328

第五组:(随机1000000)

顺序查找所需时间为:871

二叉排序树查找时间为:5

哈希表法所用查找时间为:3

3种方法的比较次数分别为:

99945005255  2838781  9985419


ps,第一个交的


你可能感兴趣的:(其它)