• 2021.11.23数据结构实验课作业——查找


    1、折半查找(必做题)

    计算机类201和202班有80位同学,学号分别为20101-20140,20201-20240,按照学号递增顺序依次坐在1-80号座位上,请编写折半查找算法帮助老师快速找到学号为X同学,若找不到该同学则输出“找不到”,若能找到则输出其座位号以及比较次数。

    2、二叉排序树(必做题)

    计算机201班有40位同学,学号分别为20101-20140,若某节《数据结构》课上有2位同学旷课,其他38位同学按进入教室的时间顺序,顺序由随机函数产生。

    (1)按照该顺序构造二叉排序树;

    (2)若给出学号X,请输出该同学是否旷课;

    3、散列表(必做题)

    计算机201班有40位同学,学号分别为20101-20140,若15位同学选修某课程,使用散列函数H(key)=(key-20100)%17进行存储,并用开放定址法的线性探测法解决冲突。

    (1)输出15位同学在散列表中的存储情况,输出格式为:存储位置,学号,如:

    0,20117

    1,20101

    4、平衡二叉树(选做题1)

    (1)给定一组无序整数,用平衡二叉树结构存储;

    (2)给定一个查找值,实现基于平衡二叉树的查找,输出是否存在,若不存在则加入平衡二叉树中;
    /*****************/

    我是真没想到高中时候学不会的平衡树到了大学没跑掉。。。。
    推荐一篇讲平衡树的博客

    线性查找(折半)

    点击查看代码LineSearch.h
    #pragma once
    #include <iostream>
    #ifndef MaxSize
    #define MaxSize 100
    #endif
    using namespace std;
    
    class LineSearch {
    public:
    	LineSearch(int a[], int n);                  //构造函数
    	~LineSearch() { }                        //析构函数为空
    	int BinSearch1(int k);                      //折半非递归查找
    	int BinSearch2(int low, int high, int k); //折半递归查找
    	void Count() {
    		cout << "查找次数: " << count << endl;
    	};
    private:
    	int data[MaxSize];                         //查找集合为整型
    	int length;
    	int count;//查找集合的元素个数
    };
    
    LineSearch::LineSearch(int a[], int n) {
    	for (int i = 1; i <= n; ++i)
    		data[i] = a[i];                          //查找集合从下标1开始存放
    	length = n;
    	count = 0;
    }
    
    int LineSearch::BinSearch1(int k) {
    	int mid, low = 1, high = length;    //初始查找区间是[1, n]
    	count = 0;
    	while (low <= high) {                 //当区间存在时
    		++count;
    		mid = (low + high) / 2;
    		if (k < data[mid])
    			high = mid - 1;
    		else if (k > data[mid])
    			low = mid + 1;
    		else return mid;                   //查找成功,返回元素序号
    	}
    	return 0;                               //查找失败,返回0
    }
    
    int LineSearch::BinSearch2(int low, int high, int k) {
    	if (low > high) return 0;                        //递归的边界条件
    	else {
    		int mid = (low + high) / 2;
    		if (k < data[mid])
    			return BinSearch2(low, mid - 1, k);
    		else if (k > data[mid])
    			return BinSearch2(mid + 1, high, k);
    		else return mid;                         //查找成功,返回序号
    	}
    }
    

    二叉搜索树

    点击查看代码BiSortTree.h
    #pragma once 
    #include<iostream>
    #include<cstring>
    #ifndef MaxSize
    #define MaxSize 100
    #endif
    using namespace std;
    
    template<typename DataType>
    struct BiNode
    {
    	DataType data;
    	BiNode* lchild, * rchild;
    };
    
    class BiSortTree {
    public:
    	BiSortTree(int a[], int n); //建立查找集合a[n]的二叉排序树
    	~BiSortTree() { Release(root); } //析构函数,同二叉链表的析构函数
    	void InOrder() { InOrder(root); } //中序遍历二叉树
    	BiNode<int>* InsertBST(int x) { return InsertBST(root, x); } //插入记录x
    	void DeleteBST(BiNode<int>* p, BiNode<int>* f); //删除f的左孩子p
    	BiNode<int>* SearchBST(int k) { return SearchBST(root, k); } //查找值为k的结点
    private:
    	void Release(BiNode<int>* bt);
    	BiNode<int>* InsertBST(BiNode<int>* bt, int x);
    	BiNode<int>* SearchBST(BiNode<int>* bt, int k);
    	void InOrder(BiNode<int>* bt); //中序遍历函数调用
    	BiNode<int>* root; //二叉排序树的根指针
    };
    
    
    void BiSortTree::InOrder(BiNode<int>* bt)
    {
    	if (bt == NULL) return;
    	else {
    		InOrder(bt->lchild);
    		cout << bt->data << "\t";
    		InOrder(bt->rchild);
    	}
    }
    
    BiNode<int>* BiSortTree::SearchBST(BiNode<int>* bt, int k)
    {
    	if (bt == NULL) return NULL;
    	if (bt->data == k) return bt;
    	if (bt->data > k) return SearchBST(bt->lchild, k);
    	return SearchBST(bt->rchild, k);
    }
    
    BiNode<int>* BiSortTree::InsertBST(BiNode<int>* bt, int x)
    {
    	if (bt == NULL) {
    		BiNode<int>* s = new BiNode<int>;
    		s->data = x;
    		s->lchild = NULL; s->rchild = NULL;
    		bt = s;
    		return bt;
    	}
    	if (bt->data > x)
    		bt->lchild = InsertBST(bt->lchild, x);
    	else	bt->rchild = InsertBST(bt->rchild, x);
    	return bt;
    }
    
    BiSortTree::BiSortTree(int a[], int n)
    {
    	root = NULL;
    	for (int i = 0; i < n; i++)
    		root = InsertBST(root, a[i]);
    }
    
    
    void BiSortTree::DeleteBST(BiNode<int>* p, BiNode<int>* f)
    {
    	if ((p->lchild == NULL) && (p->rchild == NULL)) { //p为叶子
    		f->lchild = NULL; delete p; return;
    	}
    	if (p->rchild == NULL) { //p只有左子树
    		f->lchild = p->lchild; delete p; return;
    	}
    	if (p->lchild == NULL) { //p只有右子树
    		f->lchild = p->rchild; delete p; return;
    	}
    	BiNode<int>* par = p, * s = p->rchild; //p的左右子树均不空
    	while (s->lchild != NULL) //查找最左下结点
    	{
    		par = s;
    		s = s->lchild;
    	}
    	p->data = s->data;
    	if (par == p)
    		par->rchild = s->rchild; //特殊情况,p的右孩子无左子树
    	else	par->lchild = s->rchild;
    	delete s;
    }
    
    void BiSortTree::Release(BiNode<int>* bt) {
    	if (bt == nullptr) return;
    	else {
    		Release(bt->lchild);
    		Release(bt->rchild);
    		delete bt;
    	}
    }
    
    哈希表
    点击查看代码HashTable.h
     #pragma once
    #include <iostream>
    #ifndef MaxSize
    #define MaxSize 100
    #endif
    using namespace std;
    
    class HashTable {
    public:
    	HashTable(); //构造函数,初始化空散列表
    	~HashTable() { }; //析构函数
    	int Insert(int k); //插入
    	int Search(int k); //查找
    	void Print();
    private:
    	int H(int k); //散列函数
    	int ht[MaxSize]; //闭散列表
    };
    
    HashTable::HashTable() {
    	for (int i = 0; i < MaxSize; i++)
    		ht[i] = 0; // 0表示该散列单元为空
    }
    
    int HashTable::H(int k) {
    	return (k - 20100) % 17;
    }
    
    void HashTable::Print() {
    	for (int i = 0; i < MaxSize; i++)
    		cout << i << ' ' << ht[i] << endl;
    }
    
    int HashTable::Search(int k) {
    	int i, j = H(k); //计算散列地址
    	i = j; //设置比较的起始位置
    	while (ht[i] != 0)
    	{
    		if (ht[i] == k) return i; //查找成功
    		else i = (i + 1) % MaxSize; //向后探测一个位置
    	}
    	return -1; //查找失败
    }
    
    int HashTable::Insert(int k) {
    	int i, j = H(k); //计算散列地址
    	i = j; //设置比较的起始位置
    	while (ht[i] != 0)
    	{
    		if (ht[i] == k)
    			return -1; //原有元素k,不能插入
    		else	i = (i + 1) % MaxSize; //向后探测一个位置
    	}
    	ht[i] = k;
    	return i; //返回插入位置
    }
    

    平衡二叉树

    点击查看代码SelfBalancingBST.h
    #pragma once
    #include<iostream>
    #include<cstring>
    #ifndef MaxSize
    #define MaxSize 100
    #endif
    using namespace std;
    
    inline int max(int a, int b)
    {return a > b ? a : b;}
    
    struct SBBSTNode {
    	int data, height;
    	SBBSTNode* lchild;
    	SBBSTNode* rchild;
    };
    
    class SBBiSortTree {
    public:
    	SBBiSortTree(int a[], int n); //建立查找集合a[n]的平衡二叉树
    	~SBBiSortTree() { Release(root); } //析构函数
    	void InOrder() { InOrder(root); } //中序遍历二叉树
    	void InsertBST(int x) { root = InsertBST(root, x); } //插入记录x
    	SBBSTNode* SearchBST(int k) { return SearchBST(root, k); } //查找值为k的结点
    private:
    	void Release(SBBSTNode* bt) {
    		if (bt == nullptr) return;
    		else {
    			Release(bt->lchild);
    			Release(bt->rchild);
    			delete bt;
    		}
    	}
    	SBBSTNode* LLRotate(SBBSTNode* y);//左旋
    	SBBSTNode* RRRotate(SBBSTNode* y);//右旋
    	SBBSTNode* InsertBST(SBBSTNode* bt, int x);//插入节点
    	SBBSTNode* SearchBST(SBBSTNode* bt, int k);//查找值为k的节点
    	void InOrder(SBBSTNode* bt); //中序遍历函数调用
    	SBBSTNode* root; //二叉排序树的根指针
    };
    
    int Height(SBBSTNode* bt) {//求某点的高度
    	if (bt == NULL)
    		return 0;
    	return bt->height;
    }
    
    int GetBalance(SBBSTNode* bt) {//求某点的平衡因子
    	if (bt == NULL)
    		return 0;
    	return Height(bt->lchild) - Height(bt->rchild);
    }
    
    void SBBiSortTree::InOrder(SBBSTNode* bt)
    {
    	if (bt == NULL) return;
    	else {
    		InOrder(bt->lchild);
    		cout << bt->data << "\t";
    		InOrder(bt->rchild);
    	}
    }
    
    SBBSTNode* SBBiSortTree::SearchBST(SBBSTNode* bt, int k)
    {
    	if (bt == NULL) return NULL;
    	if (bt->data == k) return bt;
    	if (bt->data > k)
    		return SearchBST(bt->lchild, k);
    	return SearchBST(bt->rchild, k);
    }
    
    SBBSTNode* SBBiSortTree::InsertBST(SBBSTNode* bt, int x)
    {
    	if (bt == NULL) {
    		SBBSTNode* s = new SBBSTNode;
    		s->data = x;
    		s->height = 1;
    		s->lchild = NULL; s->rchild = NULL;
    		return s;
    	}
    	if (x < bt->data)
    		bt->lchild = InsertBST(bt->lchild, x);
    	else	bt->rchild = InsertBST(bt->rchild, x);
    
    	bt->height = max(Height(bt->lchild), Height(bt->rchild)) + 1;
    	int balance = GetBalance(bt);
    	if (balance > 1) {
    		if (x < bt->lchild->data)//LL型
    			return LLRotate(bt);
    		else {//LR型
    			bt->lchild = RRRotate(bt->lchild);
    			return LLRotate(bt);
    		}
    	}
    	if (balance < -1) {
    		if (x >= bt->rchild->data)//RR型
    			return RRRotate(bt);
    		else {//RL型
    			bt->rchild = LLRotate(bt->rchild);
    			return RRRotate(bt);
    		}
    	}
    	return bt;
    }
    
    SBBSTNode* SBBiSortTree::LLRotate(SBBSTNode* y) {//y为最小不平衡点
    	SBBSTNode* x = y->lchild;//x是y的左儿子,要变成根
    	y->lchild = x->rchild;
    	x->rchild = y;
    
    	y->height = max(Height(y->lchild), Height(y->rchild)) + 1;
    	x->height = max(Height(x->lchild), Height(x->rchild)) + 1;
    	return x;
    }
    
    SBBSTNode* SBBiSortTree::RRRotate(SBBSTNode* y) {//y是最小不平衡点
    	SBBSTNode* x = y->rchild;//x是y的右儿子,要变成根
    	y->rchild = x->lchild;
    	x->lchild = y;
    
    	y->height = max(Height(y->lchild), Height(y->rchild)) + 1;
    	x->height = max(Height(x->lchild), Height(x->rchild)) + 1;
    	return x;
    }
    
    SBBiSortTree::SBBiSortTree(int a[], int n)
    {
    	root = NULL;
    	for (int i = 0; i < n; i++)
    		InsertBST(a[i]);
    }
    /*
    585 331 837 430 221 973 155 77 193 878
    */
    

    主函数文件

    点击查看代码main.cpp
    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include "LineSearch.h"
    #include "BiSortTree.h"
    #include "HashTable.h"
    #include "SelfBalancingBST.h"
    using namespace std;
    
    void InputLin(int Stu[]) {//第一题Stu数组初始化
    	for (int i = 1; i <= 80; ++i)
    		Stu[i] = 20100 + i + (i > 40 ? 60 : 0);
    	return;
    }
    
    void InputBin(int Stu[]) {//第二题Stu数组初始化
    	for (int i = 0; i < MaxSize; ++i)
    		Stu[i] = 0;
    	srand((int)time(0));
    	Stu[0] = rand() % 40 + 20101;
    	for (int x, i = 1; i < 38; ++i)
    	{
    		x = rand() % 40 + 20101;
    		for (int j = 0; j < i; ++j)
    		{
    			if (Stu[j] == x)
    			{
    				x = rand() % 40 + 20101;
    				j = -1;
    			}
    		}
    		Stu[i] = x;
    	}
    	return;
    }
    
    void InputHash(int Stu[]) {//第三题Stu数组初始化
    	//沿用第二题所得到的随机数组作为选课的15人
    	/*for (int i = 1; i <= 40; ++i)
    		Stu[i] = 20100 + i + (i>40 ? 60 : 0);*/
    	return;
    }
    
    void InputSBBST(int Stu[], int n) {//第四题Stu数组初始化
    	srand(time(0));
    	for (int i = 0; i < n; ++i)
    		Stu[i] = rand() % 1000;
    	cout << endl;
    	return;
    }
    
    int main()
    {
    	int Stu[MaxSize], key;//key为要查找的数值
    
    	cout << "第一题查找学号为x的学生位置" << endl;
    	InputLin(Stu);
    	LineSearch L(Stu, 80);
    	cout << "请输入要查找的学号" << endl;
    	cin >> key;
    	cout << "非递归查找座位号为:" << L.BinSearch1(key) << endl;
    	cout << "递归查找座位号为:" << L.BinSearch2(1, 80, key) << endl;
    	L.Count();
    	cout << endl;
    
    	cout << "第二题查询某学生是否旷课" << endl;
    	InputBin(Stu);
    	BiNode<int>* p = NULL;
    	BiSortTree B(Stu, 38);
    	//B.InOrder();
    	cout << "请输入查找的元素值" << endl;
    	cin >> key;
    	p = B.SearchBST(key);
    	if (p != NULL)
    		cout << "该同学未旷课" << endl;
    	else	cout << "该同学旷课" << endl;
    	cout << endl;
    	delete p;
    
    	cout << "第三题15名学生选课,输出散列表中存储状态" << endl;
    	InputHash(Stu);
    	HashTable H;
    	for (int i = 1; i <= 15; ++i)
    		H.Insert(Stu[i]);
    	for (int x, i = 1; i <= 15; ++i) {
    		x = H.Search(Stu[i]);
    		if (x != -1)
    			cout << "存储位置:" << x << "    学号: " << Stu[i] << endl;
    	}
    	cout << endl;
    
    	//使用1~1000随机数
    	cout << "第四题输入n个随机数插入平衡树,再查询某个数字是否存在" << endl;
    	int n, m;//随机数个数, 查询次数
    	cout << "请输入随机数个数: ";
    	cin >> n;
    	InputSBBST(Stu, n);
    	SBBiSortTree SBB(Stu, n);
    	SBBSTNode* q = NULL;
    	SBB.InOrder();
    	cout << endl << "请输入查询次数: ";
    	cin >> m;
    	for (int i = 0; i < m; ++i) {
    		cout << "请输入查询值: ";
    		cin >> key;
    		q = SBB.SearchBST(key);
    		if (q == NULL) {
    			SBB.InsertBST(key);
    			cout << "该值不存在,已经加入平衡二叉树" << endl;
    		}
    		else	cout << "存在" << endl;
    	}
    	delete q;
    
    	system("pause");
    	return 0;
    }
    
  • 相关阅读:
    【Todo】CSDN的《问底》系列-学习
    【Todo】深入PHP内核系列
    【转载】网络攻击技术(三)——Denial Of Service & 哈希相关 & PHP语言 & Java语言
    回溯法
    hdu 2842 Chinese Rings
    JSP 9 大内置对象详解
    用Html5结合Qt制作一款本地化EXE游戏-太空大战(Space War)
    HDU2795 billboard【转化为线段树。】
    URAL 1303
    IOS文件沙盒
  • 原文地址:https://www.cnblogs.com/kuaileyongheng/p/15723423.html
Copyright © 2020-2023  润新知