算法和数据结构

 
1.    算法和数据结构
一种说法是算法是程序的灵魂;一种说法是算法+数据结构=程序。我更加同意第一种说法。数据结构是为算法服务的。程序的特性、需求决定了需要采用何种算法,也就决定了要采用何种数据结构。编译器要求速度尽可能快,要能够处理成百上千万行代码,因此不可能采用数组或者二叉搜索树来存储数据,而只能采用hash表。如果要不停的插入、删除数据,则只能选择链表而不能采用数组。
基本的算法和数据结构就那么几种,但不同的实现产生了许多变体。这些变体各有特性,体现了和具体业务的相关性,但本质上,它还没有改变。
基本的算法有:检索、排序,具体实现的数据结构有:数组、链表、树,哈希表。检索方法一种是线性检索,适用于任何数据结构,有的是时间,还有什么事情做不了呢?一种是二分检索,这种只适合在已排序好的数组上,在二叉搜索树上检索其实也是一种二分检索,不过如果树过于倾斜,效果不太好;还有一种就是hash了。Hash是最快的,几乎能够达到O(1)的复杂度。但是Hash值得计算也是不容易的。这还是一个很慢的过程。排序算法更多的使用在数组上,链表上的排序算法好象是没有的。堆积排序或者构造二叉排序树来排序也可以。
对于不确定类型的数据怎么来排序或者检索呢?我们不可能为每种数据类型都写一个方法来排序。单根的java充分利用了动态绑定的特性,只要类实现comparable接口就可以使用通用的排序算法,C++充分利用了模版,但是需要重载operator < 和operator =操作符。至于C语言,只能采用函数指针这个古老而又实用的方法。
hash表中,我们最常用的就是用来Hash字符串。编译器充分利用了Hash表,虽然不同编译器的Hash算法不一样,但都是Hash字符串。书中提到了一个很有效的字符串Hash算法:
unsigned int hash( char* str )
{
    unsigned int h;
    unsigned char* p;
    h = 0;
        for( p = (unsigned char* )str; *p != ‘/0’; ++p ){
         h = MULTPLIER * h + *p;
    return h % nhash;
    }
}
MULITPLIER取31和37是个不错的选择,nhash也最好取一个质数,这样可以有效避免在数组大小、散列的乘数和可能的数据值之间存在公因子。
下面是一个快速排序算法,这真是个优雅的算法。
void quick_sort( int v[], int n ){
    int last, int i,
    if( n <= 1 )
        return;
    swap( v, 0, rand()%n );
    last = 0;
    for( i = 1; i < n; ++i ){
        if( v[i] < v[0] )
          swap( v, ++last, i );
    swap( v, 0, last );
    quick_sort( v, last );
    quick_sort( v + last + 1, n – last -1 );
}
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值