什么是算法? 算法在程序开发中是非常重要的内容,比如在后端开发过程对数据处理排序中,在前端开发过程中,做一些动画特效,绘制复杂的自定义视图的,高级动画等都需要用到特定的算法。为什么说是特定算法呢? 因为算法是可以分类的,常见的有排序算法,加密算法,聚类算法。那么什么是算法呢?我不想拿书上的标准或权威的释义复制到这里,我只想讲我自己的理解(也是我看了一些书之后)。**算法:解决某些问题的方法,步骤。**例如高校收集录入学生信息之后按照成绩排序,excel里面的排序功能,有排序算法,手机导航中有求最短路径的算法,等。我们大学学习的这些算法都是前人在解决这些特定问题时创造出来的,所有的东西最开始都是没有的,在遇到问题需要解决的时候,聪明的前辈想出了解决方案(算法)。
为什么要学习算法? 为了更高效的解决问题,大学学习的这些算法都是非常经典,非常实用的,我们在工作中如果需要处理相关的问题,完全可以借鉴相关的算法。这样就可以高效的解决问题了。有些算法设计的非常巧妙,非常值得我们学习,参考,训练自己的思维逻辑。我们也可以创造自己的算法。如果你的算法够NB,很可能被写入教科书。其实我们去找工作,笔试,面试都会遇到一些算法相关的题目,特别是BTA,大公司,当然有些个别公司不会面试算法。特别是小公司,创业公司一般不会。大公司为什么要面试算法呢?其实前面已经提了,1.可以高效解决相关问题,2体现逻辑思维能力。为什么小公司,创业公司一般不会面试算法呢? 我简单分析一下:1.最重要的一点公司业务用不到,如果需要用到,他们肯定会要求有相关领域的开发经验,很多情况不会算法也可以很好完成开发。他们招聘的更多是技工,能熟练开发应用就OK了。2.好的学校,优秀的毕业生一般不会选择小公司,普通学校毕业生,专科,培训出来的没学过算法,或者学过,但是都忘得差不多了。如果他们要求很高,就招不到人。以前做计算机的比较少,人才也比较少所以要求没那么高,现在计算机的毕业生越来越多,培训的也很多,招聘要求也开始慢慢的提高,这是正常市场竞争机制。
现在回到正题。 排序算法有很多种,下面就一一讲解最常见,最基础的算法。有:冒泡排序,选择排序,插入排序,归并排序,快速排序 1.冒泡排序? 顾名思义,排序过程就像是水里面冒泡的过程。只是形象的比喻罢了。 核心思想:遍历每次比较两个相邻的元素,将较大的元素交换至右端。
例如:7,5,1,9,4,16,15,2进行从小到大排序 第一轮: 比较7>5,交换位置,5,7,1,9,4,16,15,2 比较7> 1,交换位置,5,1,7,9,4,16,15,2 比较7< 9,不需要交换位置,5,1,7,9,4,16,15,2 比较9> 4,交换位置,5,1,7,4,9,16,15,2 比较9< 16,不需要交换位置,5,1,7,4,9,16,15,2 比较15>15,交换位置,5,1,7,4,9,15,16,2 比较16>2,交换位置,5,1,7,4,9,15,2,16 这样就找到最大的数据,放到了最右边 让后对剩余数据重复之前的操作,完成排序 代码实现: 需要两层循环,第一层循环i表示排序的轮数,第二层循环j表示控制遍历进行比较。
public static void bubbleSort(int[] arr) { if (arr == null || arr.length < 2) { return; } //外层循环只是控制遍历次数,次数比数组长度少1,因为剩最后一个不需要比较了 for (int i = 1; i < arr.length; i++) { for (int j = 0; j < arr.length - i; j++) { if (arr[j] > arr[j + 1]) { int temp = arr[j]; arr[j] = arr[j + 1]; arr[j + 1] = temp; } } } }分析: 第一轮需要比较n-1次,第二轮n-2次,第n-1轮需要比较1次 总共需要比较(n-1)+(n-2)+…+1 次 N个元素排序,需要比较n(n-1)/2次;时间复杂度O(n^2) ,不过交换次数根据数据的不同有所改变。
2. 选择排序 算法核心思想:遍历整个数列,找出最小值,与最左边的数据交换。遍历剩余数列找的最小值,重复上述过程。
算法都是在不断改进的,上面讲到的冒泡排序,交换次数可能会很多,如何优化呢?能不能减少交换次数呢?前辈们发明了另外的排序算法----选择排序,它的比较次数与冒泡排序相同,但交换次数要小于冒泡排序。当数据量较大时,效率会有很大的提升,但时间复杂度仍为O(n*n)
处理过程像是一副打乱的扑克牌假如只有10张,混乱的放在地上,你需要按顺序整理好,你会不会像上面这样, 1.先找到最小的,放在手里(手里有一张最小的,地上剩余9张) 2.从剩余的9张中找到最小的(手里有2张排好序的,地上剩余8张) 3.重复步骤2直到地上没有牌(手上10张排好序的,地上剩余0张) 这其实类似于选择排序。是不是很好理解?当然也有些不同,上面的处理过程,手里,地上像是需要两个存储空间,两个数组,我们能不能节省空间(算法的好坏需要衡量空间和时间两个重要指标),只使用一个空间可以吗?当然。这就是交换位置,找到最小的与最左边的交换。 下面看代码如何实现: java版本
public static void selectSort(int[] x) { if (x == null || x.length < 2) { return; } int temp = 0; for (int i = 0; i < x.length; i++) { int min = i; for (int j = i; j < x.length; j++) { if (x[j] <= x[min]) { min = j; } } temp = x[min]; x[min] = x[i]; x[i] = temp; } }分析: 第一轮需要比较n-1次,第二轮n-2次,第n-1轮需要比较1次 总共需要比较(n-1)+(n-2)+…+1 次. N个元素排序,需要比较n(n-1)/2次;时间复杂度O(n^2) ,不过交换次数每轮最多只有1一次,当数据量较大时,效率比冒泡排序会有很大的提升,但时间复杂度仍为O(nn) 3.插入排序 插入排序是比冒泡,选择排序更优秀的排序算法,虽然时间复杂度仍然为O(nn),但是却比冒泡排序和选择排序快很多
核心思想: 从序列左端开始依次对数据进行排序的算法,在排序过程中,左边的数据陆续归位,而右侧留下的就是还未排序的数据。插入排序的思路就是从右侧的未排序区域内取出一个数据,然后将它插入到已排序区域内合适的位置上。 我们再用扑克牌的例子。处理过程像是一副打乱的扑克牌假如只有40张,混乱的放在地上,你需要按顺序整理好,你会怎么做? 如果有10张,你可能会像选择排序那样,一眼就能找到最小的?进行选择排序。如果有40张,或者更多,这时候找最小的是不是有些困难?更多的时候我们就,按照顺序,先拿一张,再去一张放到合适的位置,继续取地上的牌,插入到合适的位置。这个过程就是插入排序。
代码实现:
//从小到大排序 public static void insertSort(int[] array) { for (int i = 1; i < array.length; i++) { int key = array[i]; int j = i - 1; while (j >= 0 && array[j] > key) { array[j + 1] = array[j]; j--; } array[j + 1] = key; } }