找个地方吧 关注:17贴子:743
  • 2回复贴,共1
实验: 简单查找算法
一. 需求和规格说明:
查找算法这里主要使用了顺序查找,折半查找,二叉排序树查找和哈希表查找四种方法。
设计思想:
开始的时候提示输入一组数据。并存入一维数组中,接下来调用一系列查找算法对其进行处理。顺序查找只是从头到尾进行遍历。二分查找则是先对数据进行排序,然后利用三个标志,分别指向最大,中间和最小数据,接下来根据待查找数据和中间数据的比较不断移动标志,直至找到。二叉排序树则是先构造,构造部分花费最多的精力,比根节点数据大的结点放入根节点的右子树,比根节点数据小的放入根节点的左子树,其实完全可以利用递归实现,这里使用的循环来实现的,感觉这里可以尝试用递归。当二叉树建好后,中序遍历序列即为由小到大的有序序列,查找次数不会超过二叉树的深度。这里还使用了广义表输出二叉树,以使得更直观。哈希表则是利用给定的函数式建立索引,方便查找。
二. 设计表示:
三. 实现注释:
其实查找排序这部分和前面的一些知识联系的比较紧密,例如顺序表的建立和实现,顺序表节点的排序,二叉树的生成和遍历,这里主要是中序遍历。应该说有些知识点较为熟悉,但在实现的时候并不是那么顺利。在查找到数据的时候要想办法输出查找过程的相关信息,并统计。这里顺序查找和折半查找均使用了数组存储的顺序表,而二叉树则是采用了链表存储的树形结构。为了直观起见,在用户输入了数据后,分别输出已经生成的数组和树。折半查找由于只能查找有序表,因此在查找前先调用函数对数据进行了排序。
在查找后对查找数据进行了统计。二叉排序树应该说由于有了之前二叉树的基础,并没有费太大力气,主要是在构造二叉树的时候,要对新加入的节点数据和跟数据进行比较,如果比根节点数据大则放在右子树里,如果比根节点数据小则放入左子树。建立了二叉树后,遍历和查找就很简单了。具体代码见源代码部分。
5.详细设计表示:
6.用户手册:
程序运行后,用户首先要输入数据的个数。接下来输入一组数据并根据提示进行顺序查找,二分查找,二叉排序树查找和哈希表查找等操作,由于操作直接简单这里不再详述。
8.源代码清单和结果:
#include <stdio.h>
#define LENGTH 100
#include <stdlib.h>
#include <time.h>
#define INFMT "%d"
#define OUTFMT "%d "
/* #define NULL 0L */
#define BOOL int
#define TRUE 1
#define FALSE 0
#define LEN 10000
typedef int ElemType;
typedef struct BSTNode
{
ElemType data;
struct BSTNode *lchild, *rchild;
} BSTNode, *BSTree;
typedef BSTree BiTree;
/* 插入新节点 */
void Insert(BSTree *tree, ElemType item)
{
BSTree node = (BSTree)malloc(sizeof(BSTNode));
node->data = item;
node->lchild = node->rchild = NULL;
if (!*tree)
*tree = node;
else
{
BSTree cursor = *tree;
while (1)
{
if (item < cursor->data)
{
if (NULL == cursor->lchild)
{
cursor->lchild = node;
break;
}
cursor = cursor->lchild;
}
else
{
if (NULL == cursor->rchild)
{
cursor->rchild = node;
break;
}
cursor = cursor->rchild;
}
}
}
return;
}
void showbitree(BiTree T)
// 递归显示二叉树的广义表形式
{
if(!T){printf("空");return;}
printf("%d",T->data);// 打印根节点
if(T->lchild ||T->rchild)
{
putchar('(');
showbitree(T->lchild);// 递归显示左子树
putchar(',');
showbitree(T->rchild);// 递归显示右子树
putchar(')');
}
}
/* 查找指定值 */
BSTree Search(BSTree tree, ElemType item)
{
BSTree cursor = tree;
while (cursor)
{
if (item == cursor->data)
return cursor;
else if ( item < cursor->data)
cursor = cursor->lchild;
else
cursor = cursor->rchild;
}
return NULL;
}
/* 中缀遍历 */
void Inorder(BSTree tree)
{
BSTree cursor = tree;
if (cursor)
{
Inorder(cursor->lchild);
printf(OUTFMT, cursor->data);
Inorder(cursor->rchild);
}
}
/* 回收资源 */
void Cleanup(BSTree tree)
{
BSTree cursor = tree, temp = NULL;
if (cursor)
{
Cleanup(cursor->lchild);
Cleanup(cursor->rchild);
free(cursor);
}
}
void searchtree(BSTree root)
{
char choice;
printf("中序遍历的结果为:\n");
Inorder(root);
printf("\n\n");
ElemType item;
BSTree ret;
/* 二叉排序树的查找测试 */
do
{
printf("\n请输入查找数据:");
scanf("%d", &item);
getchar();
printf("Searching...\n");
ret = Search(root, item);
if (NULL == ret)
printf("查找失败!");
else
printf("查找成功!");


IP属地:四川1楼2013-11-05 19:47回复
    printf("\n继续测试按y,退出按其它键。\n");
    choice = getchar();
    } while (choice=='y'||choice=='Y');
    Cleanup(root);
    }
    searchhash(int *arr,int n)
    {
    int a[10];
    int b,i,j,c;
    j=1;
    for(i=0;i<9;i++)
    a[i]=0;
    printf("以下为哈希表输出\n");
    for(i=0;i<n;i++)
    {
    c=arr[i]%7;
    A:if(a[c]==0)a[c]=arr[i];
    else {c=(c+1)%7;j++;a[c]++;goto A;}
    printf("\n%d在哈希表的第%d位,第%d次放入哈希表\n",arr[i],c,j);
    j=1;}
    }
    void SequenceSearch(int *fp,int Length);
    void Search(int *fp,int length);
    void Sort(int *fp,int length);
    void SequenceSearch(int *fp,int Length)
    {
    int data;
    printf("开始使用顺序查询.\n请输入你想要查找的数据.\n");
    scanf("%d",&data);
    for(int i=0;i<Length;i++)
    if(fp[i]==data)
    {
    printf("经过%d次查找,查找到数据%d.\n",i+1,data);
    return ;
    }
    printf("经过%d次查找,未能查找到数据%d.\n",i,data);
    }
    void Search(int *fp,int length)
    {
    int data;
    printf("开始使用顺序查询.\n请输入你想要查找的数据.\n");
    scanf("%d",&data);
    printf("由于二分查找法要求数据是有序的,现在开始为数组排序.\n");
    Sort(fp,length);
    printf("数组现在已经是从小到大排列,下面将开始查找.\n");
    int bottom,top,middle;
    bottom=0;
    top=length;
    int i=0;
    while (bottom<=top)
    {
    middle=(bottom+top)/2;
    i++;
    if(fp[middle]<data)
    {
    bottom=middle+1;
    }
    else if(fp[middle]>data)
    {
    top=middle-1;
    }
    else
    {
    printf("经过%d次查找,查找到数据%d.\n",i,data);
    return;
    }
    }
    printf("经过%d次查找,未能查找到数据%d.\n",i,data);
    }
    void Sort(int *fp,int length)
    {
    printf("现在开始为数组排序,排列结果将是从小到大.\n");
    int temp;
    for(int i=0;i<length;i++)


    IP属地:四川5楼2013-11-05 19:52
    回复
      for(int j=0;j<length-i-1;j++)
      if(fp[j]>fp[j+1])
      {
      temp=fp[j];
      fp[j]=fp[j+1];
      fp[j+1]=temp;
      }
      printf("排序完成!\n下面输出排序后的数组:\n");
      for(int k=0;k<length;k++)
      {
      printf("%5d",fp[k]);
      }
      printf("\n");
      }
      struct hash
      { int key;
      int si;
      };
      struct hash hlist[11];
      int i,adr,sum,d;
      float average;
      void chash(int *arr,int n)
      { for(i=0;i<11;i++)
      { hlist[i].key=0;
      hlist[i].si=0;
      }
      for(i=0;i<n;i++)
      { sum=0;
      adr=(3*arr[i])%11;
      d=adr;
      if(hlist[adr].key==0)
      { hlist[adr].key=arr[i];
      hlist[adr].si=1;
      }
      else { do
      {d=(d+(arr[i]*7)%10+1)%11;
      sum=sum+1;
      }while(hlist[d].key!=0);
      hlist[d].key=arr[i];
      hlist[d].si=sum+1;
      } }
      }
      void dhash(int *arr,int n)
      { printf("哈希表显示为:");
      for(i=0;i<11;i++)
      printf("%4d",i); printf("\n");
      printf("哈希表关键字:");
      for(i=0;i<11;i++)
      printf("%4d",hlist[i].key);


      IP属地:四川6楼2013-11-05 19:52
      回复