数据结构课程设计综合查找算法的实现.docx
《数据结构课程设计综合查找算法的实现.docx》由会员分享,可在线阅读,更多相关《数据结构课程设计综合查找算法的实现.docx(29页珍藏版)》请在冰豆网上搜索。
数据结构课程设计综合查找算法的实现
一、问题描述
1、顺序表查找的问题描述
顺序查找又称为线性查找,它是一种最简单、最基本的查找方法。
从顺序表的一端开始,依次将每一个数据元素的关键字值与给定Key进行比较,若某个数据元素的关键字值等于给定值Key,则表明查找成功;若直到所有的数据元素都比较完毕,仍找不到关键字值为Key的数据元素,则表明查找失败。
2、有序表的查找问题描述
折半查找也称为二分查找,作为二分查找对象的数据必须是顺序存储的有序表,通常假定有序表是按关键字值从小到大排列有序,即若关键字值为数值,则按数值有序;若关键字值是字符数据,则按对应的Unicode码有序。
二分查找的基本思想:
首先取整个有序表的中间记录的关键字值与给定值相比较,若相等,则查找成功;否则以位于中间位置的数据元素为分界点,将查找表分为左右两个子表,并判断待查找的关键字值Key是在左子表还是在右子表,再在子表中重复上述步骤,直到待查找的关键字值Key的记录或子表长度为0。
3、哈希表查找的问题描述
在哈希表上进行查找的过程是要给定要查找的关键字的值,根据构造哈希表时设定的哈希函数求得哈希地址,若此哈希地址上为空,即没有数据元素,则查找不成功;否则比较关键字,若相等,则查找成功;若不相等,则根据构造哈希表时设置的处理冲突的方法找下一个地址,知道某个位置上为空或者关键字比较相等为止。
哈希表是在关键字和存储位置之间直接建立了映像,但由于冲突的产生,哈希表的查找过程仍然是一个和关键字比较的过程。
因此,仍需用平均查找长度来衡量哈希表的查找效率。
查找过程中与关键字比较的次数取决于构造哈希表是选择的哈希函数和处理冲突的方法。
哈希函数的“好坏”首先影响出现冲突的频率,假设哈希函数是均匀的,即它对同样一组随机的关键字出现冲突的可能性是相同的。
因此哈希表的查找效率主要取决于构造哈希表时处理冲突的方法。
4、二叉排序树的查找问题描述
在顺序表的3种查找方法中,二分查找具有最高的效率,但是由于二分查找要求表中记录按关键字有序,且不能用链表做存储结构,因此当表的插入、删除操作非常频繁时,为维护表的有序性,需要移动表中很多记录。
这种由移动记录引起的额外时间开销,就会抵消二分查找的优点。
这里讨论的不仅是二叉排序树具有二分查找的效率,同时又便于在查找表中进行记录的增加和删除操作。
5、界面设计模块问题描述
设计一个菜单模式界面,让用户可以选择要查找的方式,界面上还有退出按钮,可以退出程序。
界面要求简洁明了,便于使用。
6、按钮动作命令模块问题描述
在设计好图形界面后,就必须对相应的按钮进行事件驱动程序设计。
运行Java图形用户界面程序时,程序与用户交互,比如说,在框架中显示多个按钮,当点击按钮时,就会从按钮触发一个事件。
同时,查找的操作必须要有输入和输出,则需要使用对话框和命令窗口进行输入关键字和输出结果。
二、问题分析
按钮时事件的源。
图形界面中一共有5个按钮,先注册按钮,再创建监听器对象,当按钮上有行为要发生时,按钮通过监听器的actionPerformed方法通知监听器。
点击按钮会使监听器中actionPerformed方法被调用。
首先,点击一个按钮,从e.getActionCommand()方法从按钮返回行为命令,按钮的行为命令就是按钮的文本。
调用各查找方法,之后输出查找结果。
拿“顺序表的查找”按钮来说,点击之后,如果按钮的行为命令是"顺序表的查找",则按顺序表的特点先建立一个存储结构为20的顺序表,利用JOptionPane.showInputDialog弹出输入对话框,让用户输入表长,定义一个整形变量强制转化获取到字符串型的输入。
然后利用java.util.Scanner类从控制台读关键字的序列,存放在记录顺序表中。
利用对话框输入待查找的关键字,强制转化成KeyType型。
最后,调用顺序查找的seqSearch方法,利用JOptionPane.showMessageDialog输出运行查找结果。
三、数据结构描述
publicvoidactionPerformed(ActionEvente){
Stringcommand=e.getActionCommand();
........
//顺序表的查找
if(command.equals("顺序表的查找")){
.........
}
//有序表的动作实现
if(command.equals("有序表的查找")){
.............
}
//二叉排序树的动作实现
if(command.equals("二叉排序树的查找")){
..........
}
//哈希表开放地址法的查找
if(command.equals("哈希表开放地址法的查找")){
...........
}
//退出
if(command.equals("退出"))
System.exit(0);
}
四、算法设计
我负责的是按钮动作的实现。
1、流程图
2、具体算法
if(command.equals("顺序表的查找")){
System.out.println("创建顺序查找表");
ST=newSeqList(20);
Scannersc1=newScanner(System.in);
Stringtmp1=JOptionPane.showInputDialog(this,"请输入查找表的表长:
");
intn=Integer.parseInt(tmp1);
KeyType[]k=newKeyType[n];
System.out.print("请输入查找表中的关键字序列:
");
for(inti=0;ik[i]=newKeyType(sc1.nextInt());
}
for(inti=1;iRecordNoder=newRecordNode(k[i-1]);
try{
ST.insert(i,r);
}catch(Exceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
}
Stringtmp2=JOptionPane.showInputDialog(this,"请输入待查找的关键字:
");
intn1=Integer.parseInt(tmp2);
key1=newKeyType(n1);
JOptionPane.showMessageDialog(null,"seqSearch("+key1.getKey()+")="+ST.seqSearch(key1));
}
//有序表的动作实现
if(command.equals("有序表的查找")){
ST=newSeqList(20);
Scannersc1=newScanner(System.in);
Stringtmp1=JOptionPane.showInputDialog(this,"请输入查找表的表长:
");
intn=Integer.parseInt(tmp1);
KeyType[]k=newKeyType[n];
System.out.print("请输入查找表中的关键字序列:
");
for(inti=0;ik[i]=newKeyType(sc1.nextInt());
}
for(inti=1;iRecordNoder=newRecordNode(k[i-1]);
try{
ST.insert(i,r);
}catch(Exceptione1){
//TODOAuto-generatedcatchblock
e1.printStackTrace();
}
}
Stringtmp2=JOptionPane.showInputDialog(this,"请输入待查找的关键字:
");
intn1=Integer.parseInt(tmp2);
key2=newKeyType(n1);
JOptionPane.showMessageDialog(null,"binarySearch("+key2.getKey()+")="+ST.binarySearch(key2));
}
//二叉排序树的动作实现
if(command.equals("二叉排序树的查找")){
BSTreebstree=newBSTree();
Scannersc1=newScanner(System.in);
Stringtmp1=JOptionPane.showInputDialog("请请输入二叉排序树的结点个数:
");
intn=Integer.parseInt(tmp1);
System.out.print("请输入结点的关键字序列:
");
for(inti=0;ibstree.insertBST(sc1.nextInt());
}
System.out.println("\n创建的二叉排序树的中序遍历序列为:
");
bstree.inOrderTraverse(bstree.getRoot());
System.out.println();
Stringtmp2=JOptionPane.showInputDialog("请输入关键字");
intkey3=Integer.parseInt(tmp2);;
BiTreeNodefound=bstree.searchBST(key3);
if(found!
=null){
JOptionPane.showMessageDialog(null,"查找成功!
");
}
else{
JOptionPane.showMessageDialog(null,"查找失败!
");
}
}
//哈希表开放地址法的查找
if(command.equals("哈希表开放地址法的查找")){
HashTableT=null;
//建立待查找的哈希表
T=newHashTable(20);
Scannersc1=newScanner(System.in);
System.out.print("请输入关键字的个数:
");
intn=sc1.nextInt();
System.out.print("请输入查找表中的关键字序列:
");
for(inti=0;iT.hashInsert(sc1.nextInt());
}
System.out.println("创建的哈希表为:
");
T.Hashdisplay();
Stringtmp2=JOptionPane.showInputDialog(this,"请输入待查找的关键字:
");
intn1=Integer.parseInt(tmp2);
RecordNodep=T.hashSearch(n1);
if((p.getKey()).compareTo(n1)==0)
JOptionPane.showMessageDialog(null,"查找成功!
");
else
JOptionPane.showMessageDialog(null,"查找失败!
");
}
//退出
if(command.equals("退出"))
System.exit(0);
}
五、详细程序清单
packagepackage1;
importjava.util.Scanner;
importjava.awt.BorderLayout;
importjava.awt.GridLayout;
importjava.awt.event.ActionEvent;
importjava.awt.event.ActionListener;
importjavax.swing.ImageIcon;
importjavax.swing.JButton;
importjavax.swing.JFrame;
importjavax.swing.JLabel;
importjavax.swing.JOptionPane;
importjavax.swing.JPanel;
publicclassSearchextendsJFrameimplementsActionListener{
privateImageIconusIcon=newImageIcon("src/usIcon.jpg");
privateJButtonbtnSeq=newJButton("顺序表的查找");
privateJButtonbtnBinary=newJButton("有序表的查找");
privateJButtonbtnHash1=newJButton("哈希表开放地址法的查找");
privateJButtonbtnBST=newJButton("二叉排序树的查找");
privateJButtonbtnQuit=newJButton("退出");
publicSearch(){
load();
}
publicvoidload(){
JPaneljp1=newJPanel();
JPaneljp2=newJPanel(newBorderLayout());
GridLayoutgrid=newGridLayout(2,2);
jp1.add(btnSeq);
jp1.add(btnBinary);
jp1.add(btnHash1);
jp1.add(btnBST);
jp2.add(jp1,BorderLayout.NORTH);
jp2.add(btnQuit);
jp1.setLayout(grid);
this.add(newJLabel(usIcon),BorderLayout.NORTH);
this.add(jp2,BorderLayout.SOUTH);
this.setTitle("查找");
this.setSize(550,500);
this.setVisible(true);
this.setResizable(false);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.btnSeq.setActionCommand("顺序表的查找");
this.btnBinary.setActionCommand("有序表的查找");
this.btnHash1.setActionCommand("哈希表开放地址法的查找");
this.btnBST.setActionCommand("二叉排序树的查找");
this.btnQuit.setActionCommand("退出");
btnSeq.addActionListener(this);
btnBinary.addActionListener(this);
btnHash1.addActionListener(this);
btnBST.addActionListener(this);
btnQuit.addActionListener(this);
}
classRecordNode{//记录结点类
privateComparablekey;//关键字
privateObjectelement;//数据元素
publicObjectgetElement(){
returnelement;
}
publicvoidsetElement(Objectelement){
this.element=element;
}
publicComparablegetKey(){
returnkey;
}
publicvoidsetKey(Comparablekey){
this.key=key;
}
publicRecordNode(Comparablekey){//构造方法1
this.key=key;
}
publicRecordNode(Comparablekey,Objectelement){//构造方法2
this.key=key;
this.element=element;
}
publicStringtoString(){//覆盖toString()方法
return"["+key+","+element+"]";
}
}
classKeyTypeimplementsComparable{//记录关键字类
privateintkey;//关键字
publicKeyType(){
}
publicKeyType(intkey){
this.key=key;
}
publicintgetKey(){
returnkey;
}
publicvoidsetKey(intkey){
this.key=key;
}
publicintcompareTo(KeyTypeanother){//覆盖Comparable接口中比较关键字大小的方法
intthisVal=this.key;
intanotherVal=another.key;
return(thisVal-1:
(thisVal==anotherVal?
0:
1));
}
}
classSeqList{//顺序查找表类
privateRecordNode[]r;//顺序表记录结点数组
privateintcurlen;//顺序表长度,即记录个数
//顺序表的构造方法:
构造一个存储空间容量为maxSize的顺序表
publicSeqList(intmaxSize){
this.r=newRecordNode[maxSize];//为顺序表分配maxSize个存储单元
this.curlen=0;//置顺序表的当前长度为0
}
//求顺序表中的数据元素个数并由函数返回其值
publicintlength(){
returncurlen;//返回顺序表的当前长度
}
publicintgetCurlen(){
returncurlen;
}
publicvoidsetCurlen(intcurlen){
this.curlen=curlen;
}
/*在当前顺序表的第i个结点之前插入一个RecordNode类型的结点x,其中i取值范围为:
0≤i≤curlen。
如果i值不在此范围则抛出异常,当i=0时表示在表头插入一个数据元素x,当i=curlen时表示在表尾插入一个数据元素x*/
publicvoidinsert(inti,RecordNodex)throwsException{
if(curlen==r.length-1){//判断顺序表是否已满,0号存储单元不存放元素
thrownewException("顺序表已满");
}
if(i<0||i>curlen+1){//i小于0或者大于表长
thrownewException("插入位置不合理");
}
for(intj=curlen;j>i;j--){
r[j+1]=r[j];//插入位置及之后的元素后移
}
r[i]=x;//插入x
this.curlen++;//表长度增1
}
/*顺序查找:
从顺序表r[1]到r[n]的n个元素中顺序查找出关键字为key的记录,若查找成功返回其下标,否则返回-1*/
publicintseqSearch(Comparablekey){
inti=1,n=length();
while(i=0){
i++;
}
if(ireturni;
}else{
return-1;
}
}
/*二分查找:
数组元素已按升序排列,从顺序表r[1]到r[n]的n个元素中查找出关键字为key的元素,若查找成功返回元素下标,否则返回-1*/
publicintbinarySearch(Comparablekey){
if(length()>0){
intlow=1,high=length();//查找范围的下界和上界
while(low<=high){
intmid=(low+high)/2;//中间位置,当前比较元素位置
//System.out.print(r[mid].getKey()+"?
");
if(r[mid].getKey().compareTo(key)==0){
returnmid;//查找成功
}elseif(r[mid].getKey().compareTo(key)>0){//给定值更小
high=mid-1;//查找范围缩小到前半段
}else{
low=mid+1;//查找范围缩小到后半段
}
}
}
return-1;//查找不成功
}
}
//二叉树的二叉链表的结点类
classBiTr