自行设计数据结构如通讯录(包括电话号码、用户名、地址,
以电话号码为关键字)、学生信息(包括学号、姓名、性别、年龄等,
以学号为关键字)、或者学生成绩(包括学号、姓名、班级、成绩等,
以学号为关键字)等等,完成以下功能:
(1)建立顺序表,采用顺序查找的方法按照关键字进行查找
并显示相应的记录,并显示查找的过程即跟关键字比较的顺序,计算
查找成功情况下的平均查找长度。
(2)对无序的记录按照关键字首先排序,然后采用折半查找
的方法对数据按照关键字进行查找,并显示查找的过程即跟关键字比
较的顺序,计算查找成功情况下的平均查找长度。
(3)对块内无序、块间有序的数据首先建立索引表,采用分
块查找的方法对数据按照关键字进行查找,并显示查找的过程即跟关
键字比较的顺序,计算查找成功情况下的平均查找长度。
(4)将数据按照关键字的大小插入到二叉排序树中,在二叉
排序树中对数据进行插入、查找、删除等操作,计算查找成功情况下
的平均查找长度。
(5)建立散列表,散列函数自行设计,解决冲突的方法可以
任选线性探测、二次探测和链地址法中的一种。在散列表中对对数据
按照关键字进行查找,并显示查找的过程即跟关键字比较的顺序,计
算查找成功情况下的平均查找长度。
(6)根据实验数据分析各种查找方法的优劣及适用范围及查找性能
//顺序查找、折半查找
#include
#include
#include
using namespace std;
typedef struct
{
int id;//学号
string name;//姓名
char ch;//性别
int years;//年龄
}student;//学生信息
typedef struct
{
student data[100];//存储学生信息
int length;//顺序表长度
}SqList;//建立顺序表
void CreatList(SqList &st)//创建学生相关信息
{
int i;
cout<<“输入学生个数:”;
cin>>st.length;
for(i=0;i<st.length;i++)
{
cout<<“输入第”<<i+1<<“个学生信息:”<<endl;
cout<<“学号:”;
cin>>st.data[i].id;
cout<<“姓名:”;
cin>>st.data[i].name;
cout<<“性别:”;
cin>>st.data[i].ch;
cout<<“年龄:”;
cin>>st.data[i].years;
}
cout<<endl<<“学生信息录入完毕”<<endl<<endl;
}
void Display(SqList st)//输出学生信息
{
int i;
cout<<“输出学生信息:”<<endl;
for(i=0;i<st.length;i++)
{
cout<<“学号:”<<st.data[i].id<<endl;
cout<<“姓名:”<<st.data[i].name<<endl;
cout<<“性别:”<<st.data[i].ch<<endl;
cout<<“年龄:”<<st.data[i].years<<endl;
}
cout<<endl;
}
void SeqSearch(SqList st,int id)//顺序查找
{
int i=0;
while(i<st.length&&st.data[i].id!=id)
{
i++;
}
if(i>=st.length)
cout<<“查找失败”<<endl;
else
{
cout<<“学号:”<<st.data[i].id<<endl;
cout<<“姓名:”<<st.data[i].name<<endl;
cout<<“性别:”<<st.data[i].ch<<endl;
cout<<“年龄:”<<st.data[i].years<<endl;
}
}
void InsertSort(SqList &st)//直接插入排序
{
int i,j;
student temp;
for(i=1;i<st.length;i++)
{
if(st.data[i].id<st.data[i-1].id)
{
temp=st.data[i];
j=i-1;
do
{
st.data[j+1]=st.data[j];
j–;
}while(j>=0&&st.data[j].id>temp.id);
st.data[j+1]=temp;
}
}
}
int BinSearch(SqList st,int id)//折半查找
{
int low=0,high=st.length-1,mid;
while(low<=high)
{
mid=(low+high)/2;
if(id==st.data[mid].id)
return mid;
else if(id<st.data[mid].id)
high=mid-1;
else
low=mid+1;
}
return 0;//查找失败
}
int main()
{
SqList ST;
int id,i;
CreatList(ST);
Display(ST);
cout<<“输入要查找的学生学号:”;
cin>>id;
cout<<endl<<“顺序查找:”<<endl;
SeqSearch(ST,id);
cout<<endl<<“折半查找:”<<endl;
InsertSort(ST);
if((i=BinSearch(ST,id))!=0)
{
cout<<“学号:”<<ST.data[i].id<<endl;
cout<<“姓名:”<<ST.data[i].name<<endl;
cout<<“性别:”<<ST.data[i].ch<<endl;
cout<<“年龄:”<<ST.data[i].years<<endl;
}
else
cout<<“查找失败”<<endl;
return 0;
}
//哈希、索引、二叉排序树
#include
#include
#include <string.h>
#include <stdlib.h>
using namespace std;
typedef struct s
{
int id;
string name;
char sex;
int age;
}Student;
typedef struct in
{
int id;
int index;
}Idx;
typedef struct BiTNode
{
Student data;
struct BiTNode *lchild, *rchild;
}BiTNode,BiTree;
typedef struct hashtable
{
Student data[10];
}HashTable;
void CreatHT(HashTable&hb,Student stu,int n)//创建哈希表
{
for (int i=0;i<10;i++)
{
hb->data[i]=NULL;
}
for (int i=0;i<n;i++)
{
int adr=stu[i].id%10;
int adr1=adr;
if (hb->data[adr]NULL)
{
hb->data[adr]=&stu[i];
}
else
{
adr=(adr+1)%10;
while(hb->data[adr]!=NULL&&adr!=adr1)
{
adr=(adr+1)%10;
}
if (adradr1)
{
cout<<“哈希表满”<<endl;
}
else
hb->data[adr]=&stu[i];
}
}
}
void ListHT(HashTable&hb)//列举哈希表中元素
{
for (int i=0;i<10;i++)
{
if(hb->data[i]!=NULL)
cout<data[i]->id<<" ";
else
cout<<"NULL ";
}
}
void FindFromHT(HashTable&hb,int id)//哈希表查找
{
int adr=id%10;
int adr1=adr;
int i=1;
if(hb->data[adr]->idid)
{
cout<<“adr=id%10”<<endl;
cout<<“哈希表中第”<<i<<“次查找,查找成功”<<endl;
cout<<“学号:”<data[adr]->id<<endl;
cout<<“姓名:”<data[adr]->name<<endl;
cout<<“性别:”<data[adr]->sex<<endl;
cout<<“年龄:”<data[adr]->age<<endl;
return ;
}
else
{
cout<<“哈希表中第”<<i<<“次查找,adr=id%10”<<endl;
i++;
adr=(adr+1)%10;
while(hb->data[adr]!=NULL&&adr!=adr1)
{
if(hb->data[adr]->idid)
{
cout<<“哈希表中第”<<i<<“次查找,查找成功”<<endl;
cout<<“学号:”<data[adr]->id<<endl;
cout<<“姓名:”<data[adr]->name<<endl;
cout<<“性别:”<data[adr]->sex<<endl;
cout<<“年龄:”<data[adr]->age<<endl;
return ;
}
adr=(adr+1)%10;
cout<<“哈希表中第”<<i<<“次查找,adr=(adr+1)%10”<<endl;
i++;
}
cout<<“哈希表中没有该学号学生”<<endl;
}
}
//向下遍历,找到节点s应该插入的位置,节点有重复时,忽略这个节点
void SearchTreeNode(BiTree &root, BiTree &s) //注意:使用引用传递
{
if (root == NULL)
return;
if (s->data.id > root->data.id)
{
if (root->rchild == NULL){
root->rchild = s;
return;
}
SearchTreeNode(root->rchild, s);//s值大于根节点值,未到达叶子节点,继续向右孩子遍历
}
else if(s->data.id < root->data.id)
{
if (root->lchild == NULL)
{
root->lchild = s;
return;
}
SearchTreeNode(root->lchild, s);//s值小于根节点值,未到达叶子节点,继续向左孩子遍历
}
}
//插入一个节点,树为空,插入节点即为根节点,否则找合适的位置插入
void InsertNode(BiTree &tree, BiTree &s) //注意:使用引用传递
{
if (tree == NULL)
tree = s;
else
SearchTreeNode(tree,s);
}
//二叉排序树创建,每次增加一个结点,插到现有的二叉树上去
void CreateOrderBinaryTree(BiTree &tree,Student a,int n)
{
for (int i = 0; i < n; i++)
{
BiTree s = (BiTree)malloc(sizeof(BiTNode));
s->data = a[i];
s->lchild = NULL;
s->rchild = NULL;
InsertNode(tree,s);
}
}
//在树中插入一个节点
BiTree Insert(BiTree pRoot,Student key)
{
if (pRoot == NULL)
{
pRoot = (BiTree)malloc(sizeof(BiTNode));
pRoot->data = key;
pRoot->lchild = NULL;
pRoot->rchild = NULL;
}
else if (key.id < pRoot->data.id)
pRoot->lchild = Insert(pRoot->lchild, key);
else if (key.id>pRoot->data.id)
pRoot->rchild = Insert(pRoot->rchild, key);
else
cout << “节点已经存在” << endl;
return pRoot; //每一步递归调用都要返回,以维持原树结构的不变
}
//删除树中指定元素key
void DeleteNode(BiTree &tree, int id) //使用引用
{
if (tree == NULL)
{
cout<<“树中无该节点”<<endl;
return;
}
if (id > tree->data.id)
DeleteNode(tree->rchild, id);
else if (id < tree->data.id)
DeleteNode(tree->lchild,id);
else
{
if (tree->lchild == NULL) //左子树为空,只需要重接右子树
{
BiTree tmp = tree;
tree = tree->rchild;//传的是引用
free(tmp);
cout<<“删除成功”<<endl;
}
else if (tree->rchild==NULL) //右子树为空,只需要重接左子树
{
BiTree tmp = tree;
tree = tree->lchild;
free(tmp);
cout<<“删除成功”<<endl;
}
else
{
BiTree tmp1, tmp; //tmp为被删除节点,tmp1为tmp前驱
tmp1 = tree;
tmp = tree->lchild;
while (tmp->rchild!=NULL) //左转,向右指,直到尽头
{
tmp1 = tmp;
tmp = tmp->rchild;
}
tree->data = tmp->data;
if (tmp1 != tree)
tmp1->rchild=tmp->lchild; //tmp左子树接到前驱右子树上
else
tmp1->lchild = tmp->lchild; //tmp左子树接到前驱左子树上
free(tmp);
cout<<“删除成功”<<endl;
}
}
}
//中序遍历
void midOrderTraverse(BiTree& tree)
{
if (tree == NULL)
return;
midOrderTraverse(tree->lchild);
cout << tree->data.id<<" ";
midOrderTraverse(tree->rchild);
}
//查找
void midfind(BiTree& root,int id)
{
if (root == NULL)
return;
if (id> root->data.id)
{
if (root->rchild == NULL){
cout<<“查找失败,没有该节点”<<endl;
return;
}
midfind(root->rchild, id);//s值大于根节点值,未到达叶子节点,继续向右孩子遍历
}
else if(id < root->data.id)
{
if (root->lchild == NULL)
{
cout<<“查找失败,没有该节点”<<endl;
return;
}
midfind(root->lchild, id);//s值小于根节点值,未到达叶子节点,继续向左孩子遍历
}
else
{
cout<<“查找成功,该节点学生信息为:”<<endl;
cout<<“学号:”<data.id<<endl;
cout<<“姓名:”<< root->data.name<<endl;
cout<<“性别:”<< root->data.sex<<endl;
cout<<“年龄:”<< root->data.age<<endl;
}
}
//初始化顺序表
void InitSeq(Studentstu,int n)
{
string name;
for(int i=0;i<n;i++)
{
cout<<“输入第”<<i+1<<“个学生信息:”<<endl;
cout<<“学号:”;
cin>>stu[i].id;
cout<<“姓名:”;
cin>>stu[i].name;
cout<<“性别:”;
cin>>stu[i].sex;
cout<<“年龄:”;
cin>>stu[i].age;
}
}
//顺序显示表中元素
void listStu(Student *stu,int n)
{
for(int i=0;i<n;i++)
{
cout<<“第”<<(i+1)<<“个学生:”<<endl;
cout<<“学号:”<<stu[i].id<<endl;
cout<<“姓名:”<<stu[i].name<<endl;
cout<<“性别:”<<stu[i].sex<<endl;
cout<<“年龄:”<<stu[i].age<<endl;
cout<<endl;
}
}
//b为索引表长度
void idxSearch(Student *stu,int b,int id,int n)
{
cout<<“建立索引表:”<<endl;
Idx *idxStu=new Idx[b];
int s=(n+b-1)/b;//n个元素分成b块,每块元素个数
int j=0;
for(int i=0;i<n;i+=s)
{
idxStu[j].index=i;
idxStu[j].id=stu[i].id;
j++;
}
for(int i=0;i<b;i++)
{
cout<<“学生于顺序表中的序号:”<<(idxStu[i].index+1)<<",学生学号:"<<idxStu[i].id<<endl;
}
cout<<“在索引表中查找结果:”<<endl;
int low=0;
int high=b-1;
int mid;
int i=0;
while(low<=high)
{
mid=(low+high)/2;
if(idxStu[mid].id<id)
{
cout<<“索引表中第”<<(i+1)<<“次查找,小了”<<endl;
i++;
low=mid+1;
}
else if(idxStu[mid].id>id)
{
cout<<“索引表中第”<<(i+1)<<“次查找,大了”<<endl;
i++;
high=mid-1;
}
else
{
cout<<“索引表中第”<<(i+1)<<“次查找”<<endl;
i++;
low=mid+1;
break;
}
}
if (low-1<0)
{
cout<<“查找失败,没有id为”<<id<<“的学生”<<endl;
delete []idxStu;
return;
}
j=idxStu[low-1].index;
while(j<n&&j<(idxStu[low-1].index+s))
{
if(stu[j].id==id)
{
cout<<“第”<<low<<“块中第”<<(i+1)<<“次查找,查找成功!,该学生信息为:”<<endl;
cout<<“学号:”<<stu[j].id<<endl;
cout<<“姓名:”<<stu[j].name<<endl;
cout<<“性别:”<<stu[j].sex<<endl;
cout<<“年龄:”<<stu[j].age<<endl;
delete []idxStu;
return;
}
else
{
cout<<“第”<<low<<“块中第”<<(i+1)<<“次查找.”<<endl;
j++;
i++;
}
}
cout<<“查找失败,没有id为”<<id<<“的学生”<<endl;
delete []idxStu;
}
int main()
{
cout<<“请输入学生个数:”;
int n;
cin>>n;
Student *stu=new Student[n];
InitSeq(stu,n);
BiTree treeRoot=NULL;
CreateOrderBinaryTree(treeRoot,stu,n);
cout<<“此时顺序表中的学生:”<<endl;
listStu(stu,n);
cout<<“3.分块查找,请输入要查找学生的学号:”;
int b;
int id;
cin>>id;
cout<<“请要建立索引表的长度:”;
cin>>b;
idxSearch(stu,b,id,n);
cout<<"4.二叉排序树查找"<<endl;
cout<<"(1)根据输入的线性表创建二叉树,二叉树中序遍历:";
midOrderTraverse(treeRoot);
cout<<endl;
cout<<"(2)请输入要查找学生的学号:";
cin>>id;
midfind(treeRoot,id);
cout<<"(3)请输入要删除学生的学号:";
cin>>id;
DeleteNode(treeRoot,id);
cout<<"二叉树中序遍历:";
midOrderTraverse(treeRoot);
cout<<endl;
cout<<"5.哈希表查找"<<endl;
cout<<"创建哈希表,展示哈希表:";
HashTable *hb=new HashTable();
CreatHT(hb,stu,n);
ListHT(hb);
cout<<endl;
cout<<"请输入学生学号:";
cin>>id;
FindFromHT(hb,id);
delete []stu;
return 0;
}
来源:CSDN
作者:R&&F
链接:https://blog.csdn.net/m0_46196448/article/details/103990305