笨鸟的数据结构理解 - 数组

来源:互联网 发布:雪豹特种部队 知乎 编辑:程序博客网 时间:2024/04/30 21:58

数组

数组是最常见的数据结构了,比如电影院的一排座位,排队买票的人群,都可以看做为一堆数据的整齐排列的集合。在java中 数组里面的引用类型结构放在数组中 都是放的该数据的引用 而非真正的实体,至于值类型的话 值类型本来事先预定义的一个结构体 并且是很小的结构体,这个结构体直接由bit数据组成,int 类型最大也就占用4个字节的空间, 所以直接放在了数组中 而非是引用。(这是我的推测)。

先从最基本的学起,数组已经能够解决很大一部分数据的问题了 如果不考虑效率这些的话,后面我会写到各种各样的结构体。由数组这个结构体 能够引发很多关联的算法,例如排序。看下面的图 能稍微描述下 数组的结构 和引用内存值的关系。


我们可以利用数组这个结构作很多很多事情,比如做一个栈结构,做一个队列结构。下面我就写下 关于数组结构常用的用法。
数组排序一直是一个头疼的问题。在培训机构的时候。做过最复杂的可能就是 快速排序了。好久没用的话 其实全忘记了。比较笨的我,还是记录这里,以后常看看 ,硬记录到大脑思维上去吧。聪明的同学就不必做我这样笨方法了 ^_^.
在一个 数组中,如果需要查找到其中的数据,那么就会分 线性查找和二分查找 的方法。按照最常理稳定的逻辑在一个数组中需要查找一个需要的东西的话,从1开始逐个往后面一一对比过去。这样迟早是要找到的。把数组横向并排开来 就像一条线一样 从一端 依次对比匹配到另外一端的过程 就形象的比喻成了 线性查找。效率的话,肯定是很低的。如果有N个数,那么就会对比N个(不排除运气好的情况下,这里就说最坏的情况)。

排序的话 可以要在排序之前 对 数组里面的数据 进行依次挨个的匹配,就需要查找到查找的算法。直接看例子吧。例子后面做注释。

冒泡排序(最简单最耗费性能)

int[] arry = new int[]{4,3,2,1,4,67,7,89,3,23,56,12,44,43,45,78,12,32,0,1,2,8,6,43,93};for (int i = 0; i < arry.length; i++) { for (int j = 0; j < arry.length-1-i; j++) {if(arry[j] < arry[j+1]){int temp = arry[j];arry[j] = arry[j+1];arry[j+1] = temp;}}}

注解: 冒泡排序 以前我一直不能其理解,由于在工厂工作了2年,脑筋还真的给麻木了。。记不得又着急,所以去背死的。结果用不了多久,都给忘记了。觉得挺失败的。故这里还是自己理解好了 记录下来,以后又忘记了 也方便来这里看看 记忆一下。 终于明白了 冒泡的含义,从数组的一端,可以把最大的数字或者最小的数字给通过逐步的对比推送到另外一端,循环后这样会形成一个有序的数组,有点难以说清楚,看例子吧。我们给这个数组 排序,把最小的数字放到数组的最右边,依次给数组形成一个倒序的有序数组。比如 这个 arry 数组的 0下标的 “4” 和 1下标的 “3”,我们从0下标开始对比,首先会和它右边的 “3” 做对比,如果下标1的值大于下标0 ,那么让他们交换一下,那么就是 下标0 是“4”,下标1 是“3”,再然后我们是不是要用”3“ 去跟下标2的值 做对比,如果下标2的值又比”3“大,那么就得再次让值 ”3“ 给移动过去,如果比3小,就不用交换,进入下次循环 用下标2的值 去跟 下标3的那个值 去对比。如此循环  就像冒泡泡似的,直到在内循环中 找到一个最小的值 ,推送到最右边去。经历过上面的一次对比后,就已经找出了一个最小的值,那么接下来的循环会去找 剩余值当中 最小的。又把最小的那个值 给推送到最右边(不过这里不必要跟已经推送到右边的值去对比了。因为最右边的值已经是经过排序 确定为最小或最大的了。 你看代码 内循环条件部分 我在这里 减去了 i 值 也就是外循环的值。比如 本来第一次对比到 下标10,找到了一个最小的放到了下标10,那么第二次对比 我们就只要对比到 下标 9 就行了 这样很容易明白了吧 ^_^.  12 点了 先睡觉。下次来继续补上 。得补充精力 为明早的早起学习做准备。能看到这里的朋友,相信也是困惑于这些对于聪明人简单。对于我们却很难于想明白的死脑筋。哈哈。加油 一起努力吧。)

选择排序(稍微比冒泡优越一些)

/** * 选择排序 */public void selectionSort(){int out,in,min;//定义3个变量 min 是 指向最小数字的下标for(out = 0; out<nElems-1; out++){min = out;//循环进来的时候 默认最小的下标在排序好的数据最左边也就是out的值for(in = out+1; in<nElems; in++){/** * 当后面一个下标的值 小于a[min] 的时候, * 就把小于值的下标赋值给min,然后继续循环 * 直到循环结束 ,自然找出了 这组数据的最小 * 值的下标  */if(a[in] < a[min])min = in;}// 把这个 最小值的位置 于 排序好的值的右边一个交换。//当所有循环结束后 排序自然完成啦swap(out,min);}}private void swap(int one,int two){long temp = a[one];a[one] = a[two];a[two] = temp;}

注解:上次写到了冒泡排序后,有时间了 再次写一个稍微好一点的排序。这个排序的原理跟冒泡排序有着一样的循环去比较的过程,只不过不像冒泡排序那样一比较就交换 取而代之的是 有选择的 交换。主要是交换占据了更多的时间和消耗了更多的性能。
用人性思维的角度来看待,当一排高低不齐的人 站在你眼前的时候,作为你 是怎么去给他排序的呢?我想你肯定也是 放眼望去 在大脑中 生成一排人的影像,然后逐个的去分析哪个最高 哪个最矮,你大脑肯定也是经过了比较的。同理,我们可以用这个思维来做选择排序。如果有10 个人,那么我们首先必然要选出10个人中间最矮 或最高的。 然后把这个人给 挑选出来 ,这里按从矮到高排序,首先搜寻10 个人中 最矮的,那么必然会从第一个人开始对比到最后一个。(相当于一个循环),当找到后 就把这个人 放到最左边(数组下标0),但是一个循环的话 只能寻找出一个最矮的,那剩余的9个人怎么去比较呢。这里就要在这个找最矮的循环中 外套一个循环,外面的循环用来依次循环剩余的9个人来做对比。一旦找到一个就把那个最矮的依次放到数组的最左边(前面有一个就是数组小标1了)。如此类推,虽难10个人对比了100次,但是只交换了10次。如果是冒泡排序 那么就是比较100次 交换100次。选择排序在交换的性能消耗是是比冒泡排序优越的。


原创粉丝点击