第九章(1).顺序查找以及折半查找
来源:互联网 发布:淘宝500的充气娃娃图片 编辑:程序博客网 时间:2024/06/16 03:03
//查找表(Search Table)是由同一类型的数据元素构成的集合。由于"集合"中的数据元素之间存在完全松散的关系,因此查找表是一种非常灵便的数据结构。
//对查找表的操作经常有:(1)查询某个元素是否在表中;(2)检索某个特定元素的各种属性;(3)在查找表中插入一个元素;(4)从查找表中删去某个数据元素.//静态查找表只对查找表做前两种关于查找的操作。而动态查找表可以做后两种操作。
#include < stdio.h >
#include < stdlib.h >
#include < string.h >
//#include < limits.h >#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define OVERFLOW -2
typedef int Status ;#define N 5
typedef int KeyType ; //定义关键字的类型//-----对数值型关键字的比较--------//
#define EQ( a , b ) ( ( a ) == ( b ) )
#define LT( a , b ) ( ( a ) < ( b ) )
#define LQ( a , b ) ( ( a ) <= ( b ) )
//-----字符串型关键字的比较--------//
//#define EQ( a , b ) ( !strcmp( a , b ) )
//#define LT( a , b ) ( strcmp( a , b ) < 0 )
//#defien LQ( a , b ) ( strcmp( a , b ) <= 0 )typedef struct { //数据元素
long Number ;
char Name[ 10 ] ;
int Politics ;
int Chinese ;
int English ;
int Math ;
int Physics ;
int Chemical ;
int Biology ;
KeyType key ; //关键字 key == totalscore.
} SElemType ;typedef struct { //静态查找表的顺序存储结构
SElemType *elem ; //数据元素存储的空间基址,建表时按实际长度分配,0号单元留空.
int length ; //表长度
} SSTable ;//---------------------------------------------------------------------------//
//顺序表查找:为了提高查找效率,我们可以在每个记录中附设一个访问频度,并使顺序表中的记录始终保持按访问频率度非递减有序的次序排序,或者在每次查找后都将刚查到的记录直接移至表尾。
Status Creat_Seq( SSTable *ST , int n , SElemType *Data ) ;
Status Destroy( SSTable *ST ) ;
Status Search_Seq( SSTable ST , KeyType key ) ;
Status Traverse( SSTable ST , void( *Visit )( ElemType ) ) ;
void visit( SElemType set ) ;//---------------------------------------------------------------------------//
//以有序表表示静态查找表时,Search可以用折半查找来实现!
Status Ascend( SSTable *ST , int n , SElemType *Data ) ;//创建一个有序表
Status Search_Bin( SSTable ST , KeyType key ) ;
//折半查找效率比顺序查找效率高,但折半查找只适用于有序表,且限于顺序存储结构(对线性链无法有效地进行折半查找)
//(概率相等的情况下,折半查找的性能最优)#include "head.h"
//-----------------------------------------------------------------//
Status Creat_Seq( SSTable *ST , int n , SElemType *Data ) //创建顺序表
{
int i ;( *ST ).elem = ( SElemType * )malloc( sizeof( SElemType ) * ( n + 1 ) ) ; //0号单元不用
if( !( *ST ).elem )
{
printf( "Malloc failed!\n") ;
return ERROR ;
}for( i = 1 ; i <= n ; ++ i )
{
( *ST ).elem[ i ] = Data[ i - 1 ] ; //这样也可以!
/* ( *ST ).elem[ i ].Number = Data[ i - 1 ].Number ;
strcpy( ( *ST ).elem[ i ].Name , Data[ i - 1 ].Name ) ;
( *ST ).elem[ i ].Biology = Data[ i - 1 ].Biology ;
( *ST ).elem[ i ].Chemical = Data[ i - 1 ].Chemical ;
( *ST ).elem[ i ].Chinese = Data[ i - 1 ].Chinese ;
( *ST ).elem[ i ].English = Data[ i - 1 ].English ;
( *ST ).elem[ i ].Math = Data[ i - 1 ].Math ;
( *ST ).elem[ i ].Physics = Data[ i - 1 ].Physics ;
( *ST ).elem[ i ].Politics = Data[ i - 1 ].Politics ; */
( *ST ).elem[ i ].key = Data[ i - 1 ].Biology + Data[ i - 1 ].Chemical + Data[ i - 1 ].Chinese +
Data[ i - 1 ].English + Data[ i - 1 ].Math + Data[ i - 1 ].Physics + Data[ i - 1 ].Politics ; //key为总成绩
}
( *ST ).length = n ;return OK ;
}Status Destroy( SSTable *ST )
{
free( ( *ST ).elem ) ;
( *ST ).elem = NULL ;
( *ST ).length = 0 ;
return OK ;
}Status Search_Seq( SSTable ST , KeyType key ) //在顺序表中查找关键字等于key的数据元素,若找到则返回该元素在表中的位置,否则返回0.
{
int i ;//0号单元留空的.
ST.elem[ 0 ].key = key ; //"哨兵",目的在于免去查找过程中每一步都要检测整个表是否查找完毕(需要比较).仅仅这这个技巧的改进,就能使顺序表查找在ST.Length>=1000时,进行一次查找所需的平均时间几乎减少一半.
for( i = ST.length ; !EQ( ST.elem[ i ].key , key ) ; -- i ) ; //从后往前找,找不到时,i刚好为0
return i ;
}Status Traverse( SSTable ST , void( *Visit )( ElemType ) )
{
SElemType *p ;
int i ;p = ++ST.elem ;
for( i = 1 ; i <= ST.length ; ++ i )
{
// Visit( ST.elem[ i ] ) ;
Visit( *p++ ) ;
}
return OK ;
}void visit( SElemType set )
{
printf( "%6ld%8s :%4d,%5d,%5d,%5d,%5d,%5d,%5d,%5d\n" ,set.Number , set.Name , set.Politics , set.Chinese ,
set.English , set.Math , set.Physics , set.Chemical , set.Biology , set.key ) ;
}//--------------------------------------------------------------------------------//
Status Ascend( SSTable *ST , int n , SElemType *Data ) //有序表!非递减有序
{
int i , j , k ;Creat_Seq( ST , n , Data ) ;
for( i = 1 ; i < ( *ST ).length ; ++ i )
{
k = i ; //最小关键字的序号
( *ST ).elem[ 0 ] = ( *ST ).elem[ i ] ;for( j = i + 1 ; j <= ( *ST ).length ; ++ j )
{
if( LT( (*ST).elem[ j ].key , (*ST).elem[ 0 ].key ) ) //(*ST).elem[ 0 ].key不能改为(*ST).elem[ i ].key,否则会成为原表的倒序.
{
k = j ;
( *ST ).elem[ 0 ] = ( *ST ).elem[ j ] ; //选出最小元素
}
}if( k != i )
{
( *ST ).elem[ k ] = ( *ST ).elem[ i ] ;
( *ST ).elem[ i ] = ( *ST ).elem[ 0 ] ;
}
}return OK ;
}Status Search_Bin( SSTable ST , KeyType key ) //折半查找关键字为key的数据元素,若找到则返回该元素的位置,否则返回0.
{
int low , high , mid ; //起搜索指针的作用!low = 1 ;
high = ST.length ;while( low <= high )
{
mid = ( low + high )/2 ;
if( EQ( key , ST.elem[ mid ].key ) )
{
return mid ;
}
else
{
if( LT( key , ST.elem[ mid ].key ) )
high = mid - 1 ;
else
low = mid + 1 ;
}
}
return 0 ;
}
int main( )
{
int i , s ;
SSTable ST ;
SElemType Data[ N ] = { { 179324,"何芳芳",85,89,98,100,93,80,47 } , // 全局变量
{ 179325,"陈红",85,86,88,100,92,90,45 } ,
{ 179326,"陆华",78,75,90,80,95,88,37 } ,
{ 179327,"张平",82,80,78,98,84,96,40 } ,
{ 179328,"赵小怡",76,85,94,57,77,69,44 } } ;// Creat_Seq( &ST , N , Data ) ;
Ascend( &ST , N , Data ) ;printf( "准考证号 姓名 政治 语文 外语 数学 物理 化学 生物 总分\n" ) ;
Traverse( ST , visit ) ; //按顺序输出静态查找表printf( "请输入待查找人的总分: " ) ;
scanf( "%d" , &s ) ;
// i = Search_Seq( ST , s ) ; //顺序查找
i = Search_Bin( ST , s ) ; //折半查找
if( i )
{
printf( "该学生学号为: %4ld.\n" , ST.elem[ i ].Number ) ;
}
else
{
printf( "Sorry! 未找到该学生!\n" ) ;
}Destroy( &ST ) ;
return 0 ;
}
- 第九章(1).顺序查找以及折半查找
- 折半查找&顺序查找
- 查找:顺序查找,折半查找
- 静态查找(顺序、折半)
- 顺序查找和折半查找
- 顺序查找 折半查找 二叉排序树
- 顺序查找和折半查找
- 顺序查找和折半查找
- 顺序查找和折半查找
- 折半查找和顺序查找
- 折半查找和顺序查找
- 顺序查找和折半查找
- 顺序查找和折半查找
- 折半查找和顺序查找
- 静态查找(顺序查找和折半查找)
- php 二分查找(折半查找) 顺序查找
- (3) 查找算法 --- 顺序查找 折半查找
- 折半查找以及插入
- 第七章(8).拓扑排序
- 第七章(9).关键路径
- 第七章(10).单源最短路径
- synchronized 关键字最佳实践
- 第七章(11).每对顶点间的最短路径
- 第九章(1).顺序查找以及折半查找
- 自我摸索阶段
- Oracle与SQL Server在企业应用中的比较
- 自我学习(一)
- 【老孙随笔】搞技术永远没有出头之日吗?
- IT人不可不听的10个职场故事!
- [转]我奋斗了18年不是为了和你一起喝咖啡
- 第九章(2).次优查找树
- 第九章(4).平衡二叉树