剑指offer-算法和数据结构:查找和排序

来源:互联网 发布:js点击切换显示隐藏 编辑:程序博客网 时间:2024/05/16 12:36

和数据结构一样,算法的面试题也备受面试官的青睐,其中排序和查找是面试是考察算法的重点。
在准备面试的时候应该重点掌握二分查找、归并排序和快速排序,做到能随时正确、完整地写出它们的代码。

查找和排序都是在程序设计中常用到的算法。查找相对而言较为简单,不外乎顺序查找、二分查找、哈希表查找和二叉排序树查找。在面试的时候,不管用循环还是用递归,面试官都期待应聘者能够写出完整正确的二分查找代码。。。

提示:如果面试题是要求在排序的数组(或者部分排序的数组)中查找一个数字或者统计某个数字出现的次数,都可以尝试用二分查找算法。

哈希表和二叉排序树查找的重点在于考查对应的数据结构而不是算法。哈希表最主要的优点是我们利用它能够在O(1)时间查找某一元素,是效率最高的查找方式。但其缺点是需要额外的空间来实现哈希表。
与二叉排序树查找算法对应的数据结构是二叉搜索树。

排序比查找要复杂一些。面试官会经常要求应聘者比较插入排序、冒泡排序、归并排序、快速排序等不同算法的优劣。强烈建议应聘者在准备面试的时候,对各种排序算法的特点记牢,能够从额外空间消耗、平均时间复杂度和最差时间复杂度等方面去比较它们的优缺点。需要强调的是,很多公司的面试官喜欢在面试环节中要求应聘者写出快速排序的代码

实现快速排序算法的关键在于先在数组中选择一个数字,接下来把数组中的数字分为两部分,比选择的数字小的数字移到数组的左边,比选择的数字大的数字移到数组的右边。
下面的函数可以实现此项功能

int Partition( int data[], int length, int start, int end ){    if( data==NULL || length <= 0 || start<0 || end>=length )        throw new std::exception("Invalid Parameters");    int index = RandomInRange( start, end );  //生成一个在start和end之间的随机数    Swap( &data[index], &data[end] ); //交换两个数字,将生成的枢轴值与最后的位置值交换//将小于枢轴值的数字,放到枢轴位置的左侧;大于枢轴值的数字,放到枢轴位置的右侧     int small = start - 1;    for( index = start; index < end; ++index )    {        if( data[index] < data[end] )        {            ++small;            if( small != index )                Swap( &data[index], &data[small] );        }    }    ++small;    Swap( &data[small], &data[end] );    return small;}void QuickSort( int data[], int length, int start, int end ){    if( start==end )        return;    int index = Partition( data, length, start, end );    if( index > start )        QuickSort( data, length, start, index-1 );    if( index < end )        QuickSort( data, length, index+1, end );}

不同的排序算法使用的场合也不尽相同。快速排序虽然总体的平均效率是最好的,但也不是任何时候都是最优的算法。比如,数组本身已经排好序了,而每一轮排序的时候都是以最后一个数字作为比较的标准,此时快速排序额效率只有O(n^2)。因此在这种场合快速排序就不是最优的算法。在面试的时候,如果面试官要求实现一个排序算法,那么应聘者一定要问清楚这个排序应用的环境是什么、有哪些约束条件,在得到足够多的信息之后再选择最合适的排序算法。

面试官:请实现一个排序算法,要求时间效率O(n)
应聘者:对什么数字进行排序,有多少数字?
面试官:我们相对公司所有员工的年龄排序。公司有几万名员工。
应聘者:也就是说数字的大小是在一个较小的范围之内的,对吧?
面试官:恩,是的
应聘者:可以使用辅助空间吗?
面试官:看你用多少辅助内存。只允许使用常量大小辅助空间,不得超过O(n)。

则,代码如下

void SortAges( int ages[], int length ){    if( ages==NULL || length <= 0 )        return ;    const int oldestAge = 99;    int timesofAge[ oldestAge + 1 ];    for( int i=0; i<=oldestAge; ++i )        timesofAge[i] = 0;    for( int i=0; i<length; ++i )    {        int age = ages[i];        if( age<0 || age > oldestAge )            throw new std::exception("age out of range.");        ++timesofAge[ age ];    }    int index =0;    for( int i=0; i<=oldestAge; ++i )    {        for( int j =0; j<timesofAge[i]; ++j )        {            ages[ index ] = i;            ++index;        }    }}
0 0
原创粉丝点击