面试——七大基础算法

算法概念:算法简单来说就是指解题方案的准确而完整的描述,是一系列解决问题的清晰指令,也就是说算法告诉计算机怎么做,以此来解决问题。同一个问题存在多种算法来解决它,但是这些算法存在着优劣之分,好的算法速度快,效率高,占用空间小,差的算法不仅复杂难懂,而且效率低,对机器要求还高,当然,有时候算法之间存在一种互补关系,有些算法效率高,节省时间,但浪费空间,另外一些算法可能速度上慢些,但是空间比较节约,这时候 我们就应该根据实际要求,和具体情况来采取相应的算法来解决问题。


案例demo下载:http://download.csdn.net/download/csdn_aiyang/9943795 


一、快速排序


介绍:

快速排序是由东尼·霍尔所发展的一种排序算法。在平均状况下,排序 n 个项目要Ο(n log n)次比较。在最坏状况下则需要Ο(n2)次比较,但这种状况并不常见。事实上,快速排序通常明显比其他Ο(n log n) 算法更快,因为它的内部循环(inner loop)可以在大部分的架构上很有效率地被实现出来,且在大部分真实世界的数据,可以决定设计的选择,减少所需时间的二次方项之可能性。

步骤:

从数列中挑出一个元素,称为 "基准"(pivot),重新排序数列,所有元素比基准值小的摆放在基准前面,所有元素比基准值大的摆在基准的后面(相同的数可以到任一边)。在这个分区退出之后,该基准就处于数列的中间位置。这个称为分区(partition)操作。递归地(recursive)把小于基准值元素的子数列和大于基准值元素的子数列排序。

排序效果:

代码:

[java]  view plain  copy
  1. //快速排序  
  2.     private void quickSort(int[]  a ,int left,int right) {  
  3.         if(left < right){  
  4.             int i,j,t,temp;  
  5.             temp=a[left]; //temp中存的就是基准数  
  6.             i=left;  
  7.             j=right;  
  8.             while(i!=j)  
  9.             {  
  10.                 //顺序很重要,要先从右边开始找  
  11.                 while(a[j]>=temp && i<j)  
  12.                     j--;  
  13.                 //再找右边的  
  14.                 while(a[i]<=temp && i<j)  
  15.                     i++;  
  16.                 //交换两个数在数组中的位置  
  17.                 if(i<j)  
  18.                 {  
  19.                     t=a[i];  
  20.                     a[i]=a[j];  
  21.                     a[j]=t;  
  22.                 }  
  23.             }  
  24.             //最终将基准数归位  
  25.             a[left]=a[i];  
  26.             a[i]=temp;  
  27.             quickSort(a,left,i-1);//继续处理左边的,这里是一个递归的过程  
  28.             quickSort(a,i+1,right);//继续处理右边的 ,这里是一个递归的过程  
  29.         }  
  30.     }  
[java]  view plain  copy
  1. quickSort(a,0,a.length-1);  
(参考)同一手机效率跑分:20573

二、归并排序


介绍:

归并排序(Merge sort,台湾译作:合并排序)是建立在归并操作上的一种有效的排序算法。该算法是采用分治法(Divide and Conquer)的一个非常典型的应用。

步骤:

申请空间,使其大小为两个已经排序序列之和,该空间用来存放合并后的序列;

设定两个指针,最初位置分别为两个已经排序序列的起始位置;

比较两个指针所指向的元素,选择相对小的元素放入到合并空间,并移动指针到下一位置;

重复步骤3直到某一指针达到序列尾;

将另一序列剩下的所有元素直接复制到合并序列尾。

排序效果:

三、堆排序


介绍:

堆积排序(Heapsort)是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆性质:即子结点的键值或索引总是小于(或者大于)它的父节点。

步骤:

比较复杂,自己上网查一下吧~

排序效果:

四、选择排序

介绍:

选择排序(Selection sort)是一种简单直观的排序算法。它的工作原理如下。首先在未排序序列中找到最小元素,存放到排序序列的起始位置,然后,再从剩余未排序元素中继续寻找最小元素,然后放到排序序列末尾。以此类推,直到所有元素均排序完毕。

排序效果:


代码:

[java]  view plain  copy
  1. //选择排序  
  2.     public void selectSort(int[] array) {  
  3.         int min;  
  4.         int tmp = 0;  
  5.         for (int i = 0; i < array.length; i++) {  
  6.             min = array[i];  
  7.             for (int j = i; j < array.length; j++) {  
  8.                 if (array[j] < min) {  
  9.                     min = array[j];//最小值  
  10.                     tmp = array[i];  
  11.                     array[i] = min;  
  12.                     array[j] = tmp;  
  13.                 }  
  14.             }  
  15.         }  
  16.     }  
(参考)同一手机效率跑分: 16927



五、冒泡排序

介绍:

冒泡排序(Bubble Sort,台湾译为:泡沫排序或气泡排序)非常简单的排序算法。它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来。走访数列的工作是重复地进行直到没有再需要交换,也就是说该数列已经排序完成。这个算法的名字由来是因为越小的元素会经由交换慢慢“浮”到数列的顶端。


步骤:

  • 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  • 对每一对相邻元素作同样操作,从开始第一对到结尾的最后一对。在这一点,最后的元素会是最大的数。
  • 针对所有的元素重复以上的步骤,除了最后一个。
  • 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较。

代码:

[java]  view plain  copy
  1. //冒泡  
  2.    private void pubbleSort(int[] numbers) {  
  3.        int temp;//记录临时变量  
  4.        int size = numbers.length;//数组大小  
  5.        for (int i = 0; i < size - 1; i++) {  
  6.            for (int j = i + 1; j < size; j++) {//索引不同的两层for循环  
  7.                if (numbers[i] < numbers[j]) {//交互数据从大到小排列顺序  大的放前面  
  8.                    temp = numbers[i];  
  9.                    numbers[i] = numbers[j];  
  10.                    numbers[j] = temp;  
  11.                }  
  12.            }  
  13.        }  
  14.    }  
(参考)同一手机效率跑分: 11927

排序效果:


六、插入排序


介绍:

插入排序(Insertion Sort)的算法描述是一种简单直观的排序算法。它的工作原理是通过构建有序序列,对于未排序数据,在已排序序列中从后向前扫描,找到相应位置并插入。插入排序在实现上,通常采用in-place排序(即只需用到O(1)的额外空间的排序),因而在从后向前扫描过程中,需要反复把已排序元素逐步向后挪位,为最新元素提供插入空间。

步骤:

  • 从第一个元素开始,该元素可以认为已经被排序;
  • 取出下一个元素,在已经排序的元素序列中从后向前扫描;
  • 如果该元素(已排序)大于新元素,将该元素移到下一位置;
  • 重复步骤3,直到找到已排序的元素小于或者等于新元素的位置;
  • 将新元素插入到该位置中,重复步骤2。

排序代码:

[java]  view plain  copy
  1. //直接插入  
  2.     private void InsertSort(int[] a) {  
  3.         long t1 = System.nanoTime();  
  4.         //直接插入排序  
  5.         for (int i = 1; i < a.length; i++) {  
  6.             //待插入元素  
  7.             int temp = a[i];  
  8.             int j;  
  9.             for (j = i - 1; j >= 0; j--) {  
  10.                 //将大于temp的往后移动一位  
  11.                 if (a[j] > temp) {  
  12.                     a[j + 1] = a[j];  
  13.                 } else {  
  14.                     break;  
  15.                 }  
  16.             }  
  17.             a[j + 1] = temp;//插入进来  
  18.         }  
  19.     }  
(参考)同一手机效率跑分: 10000

七、希尔排序

介绍:

希尔排序,也称递减增量排序算法,是插入排序的一种高速而稳定的改进版本。基于插入排序的以下两点性质而提出改进方法的:

    • 插入排序在对几乎已经排好序的数据操作时,效率高,即可以达到线性排序的效率;
    • 但插入排序一般来说是低效的, 因为插入排序每次只能将数据移动一位。

代码:

[java]  view plain  copy
  1. //希尔排序  
  2.     private void HeerSort(int[] a) {  
  3.         int d = a.length / 2;  
  4.         while (true) {  
  5.             for (int i = 0; i < d; i++) {  
  6.                 for (int j = i; j + d < a.length; j += d) {  
  7.                     int temp;  
  8.                     if (a[j] > a[j + d]) {  
  9.                         temp = a[j];  
  10.                         a[j] = a[j + d];  
  11.                         a[j + d] = temp;  
  12.                     }  
  13.                 }  
  14.             }  
  15.             if (d == 1) {  
  16.                 break;  
  17.             }  
  18.             d--;  
  19.         }  
  20.     }  

(参考)同一手机效率跑分: 15052

排序效果:


案例demo下载

http://download.csdn.net/download/csdn_aiyang/9943795 

流行算法排序实用案例。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值