数组,在内存上给出了连续的空间.链表,内存地址上可以是不连续的,每个链表的节点包括值和下一个节点的位置(单向的一个,双向链表的话,会有两个).
数组优于链表的地方:
1.存储相同的值,数组内存空间占用的少,因为链表节点会附加上一块或两块下一个节点的信息.
2.数组内的数据可随机访问.但链表不具备随机访问性.链表在内存地址可能是分散的.所以必须通过上一节点中的信息找能找到下一个节点.
3.查找速度上数组占优势.这个也是因为内存地址的连续性的问题.
链表优于数组的地方:
1.插入与删除的操作.如果数组的中间(末尾除外)插入一个元素,那么这个元素后的所有元素的内存地址都要往后移动.删除的话同理.链表只需要更改有必要更改的节点内的节点位置信息就够了.并不需要更改节点的内存地址.
2.内存地址的利用率方面,如果没办法一次性给出数组所需的要空间,那就会提示内存不足.而链表可以是分散的空间地址. 只要存储足够不会有大小的限制。
3.链表的扩展性比数组好.因为一个数组建立后所占用的空间大小就是固定的.如果满了就没法扩展,不适合动态存储,不方便动态添加.
栈是一种特殊的线性表,插入和删除数据元素的操作只能在线性表的一端进行。后进先出(Last In First Out)。顺序栈有"上溢"和"下溢"的概念。当栈的容量有限已经满并且还要入栈时就是"上溢","上溢"也就是栈顶指针指出栈的外面,显然是出错了。反之,当栈中空了还要取数据时就是"下溢"。"下溢"本身可以表示栈为空栈,因此可以用它来作为控制转移的条件。若是栈中元素的数目变化范围较大或不清楚栈元素的数目,就应该考虑使用链式存储结构(一个无头结点的单链表)。链栈则没有上溢的限制。
队列(Queue)也是一种线性表,允许删除的一端称为队尾(rear),允许插入的一端称为队头 (Front),队列的操作原则是先进先出的。
String类:
1、indexOf(String s)
返回参数字符串s在指定字符串中首次出现的索引位置(从1开始数),如果没有检索到字符串s,该方法返回-1
2、lastIndexOf(Stringstr)
返回字符串最后一次出现的索引位置。如果没有检索到字符串str,该方法返回-1.如果lastIndexOf方法中的参数是空字符串"" ,,则返回的结果与length方法的返回结果相同。
3、charAt()方法可将指定索引处的字符返回
4、substring()方法
对字符串进行截取。这些方法的共同点就是都利用字符串的下标进行截取,且应明确字符串下标是从0开始的。在字符串中空格占用一个索引位置。
5、trim()方法
返回字符串的副本,忽略前导空格和尾部空格
6、replace(StringoldString,String newString)方法
将指定的字符或字符串替换成新的字符或字符串。替换后是一个新的字符串,原字符串不变。
7、startsWith()方法与endsWith()方法
分别用于判断字符串是否以指定的内容开始或结束。这两个方法的返回值都为boolean类型。
8、equals(Stringotherstr),equalsIgnoreCase(String otherstr)
如果两个字符串内容完全相同,则使用equals()方法比较时,返回true。同时equals()方法比较时区分大小写。equalsIgnoreCase()在比较时忽略了大小写。
9、compareTo()方法
按字典顺序比较两个字符串,该比较基于字符串中各个字符的Unicode值,如果参数字符串位于此字符串之后,则比较结果为一个负整数;如果参数字符串位于此字符串之前,则比较结果为一个正整数;如果这两个字符串相等,则结果为0.
10、toLowerCase()方法可将字符串中的所有字符从大写字母改写为小写字母,而tuUpperCase()方法可将字符串中的小写字母改写为大写字母。
11、split()方法可以使字符串按指定的分隔字符或字符串对内容进行分割,并将分割后的结果存放在字符数组中。分隔字符或字符串可以使用正则表达式。重载的方法可以限定分割次数。
HashMap 是基于“拉链法”实现的散列表。一般用于单线程程序中。
Hashtable(Hash表) 也是基于“拉链法”实现的散列表。它一般用于多线程程序中。
HashMap可以接受null(HashMapallows one null key and any number of null values.,而Hashtable则不行
HashSet实现了Set接口,它不允许集合中有重复的值,仅仅存储值。当我们提到HashSet时,第一件事情就是在将对象存储在HashSet之前,要先确保对象重写equals()和hashCode()方法,这样才能比较对象的值是否相等,以确保set中没有储存相等的对象。
当程序试图将一个 key-value对放入 HashMap 中时,程序首先根据该 key 的 hashCode() 返回值决定该 Entry 的存储位置:如果两个 Entry 的 key 的 hashCode() 返回值相同,那它们的存储位置相同。如果这两个 Entry 的 key 通过 equals 比较返回 true,新添加 Entry 的 value 将覆盖集合中原有 Entry 的 value,但 key 不会覆盖。如果这两个 Entry 的 key 通过 equals 比较返回 false,新添加的 Entry 将与集合中原有 Entry 形成 Entry 链,而且新添加的 Entry 位于 Entry 链的头部——具体说明继续看 addEntry() 方法的说明。
当向 HashMap 中添加 key-value对,由其 key 的 hashCode() 返回值决定该 key-value 对(就是 Entry 对象)的存储位置。当两个 Entry 对象的 key 的 hashCode() 返回值相同时,将由 key 通过 eqauls() 比较值决定是采用覆盖行为(返回 true),还是向 Entry 链添加(返回 false)。
http://www.cnblogs.com/devinzhang/archive/2012/01/13/2321481.html
http://blog.csdn.net/speedme/article/details/22485681
http://blog.csdn.net/chenssy/article/details/22896871
一、冒泡排序
基本思想是:两两比较相邻记录的关键字,如果反序则交换 冒泡排序时间复杂度最好的情况为O(n),最坏的情况是O(n^2) 改进思路1:设置标志位,明显如果有一趟没有发生交换(flag = flase),说明排序已经完成 改进思路2:记录一轮下来标记的最后位置,下次从头部遍历到这个位置就Ok
二、直接插入排序
将一个记录插入到已经排好序的有序表中, 从而得到一个新的,记录数增1的有序表,时间复杂度也为O(n^2), 比冒泡法和选择排序的性能要更好一些
三、简单选择排序
通过n-i次关键字之间的比较,从n-i+1 个记录中选择关键字最小的记录,并和第i(1<=i<=n)个记录交换之,尽管与冒泡排序同为O(n^2),但简单选择排序的性能要略优于冒泡排序
四、希尔排序
先将整个待排元素序列分割成若干子序列(由相隔某个“增量”的元素组成的)分别进行直接插入排序,然后依次缩减增量再进行排序,待整个序列中的元素基本有序(增量足够小)时,再对全体元素进行一次直接插入排序。其时间复杂度为O(n^3/2),要好于直接插入排序的O(n^2)
五、归并排序
假设初始序列含有n个记录,则可以看成n个有序的子序列,每个子序列的长度为1,然后两两归并,得到(不小于n/2的最小整数)个长度为2或1的有序子序列,再两两归并,...如此重复,直至得到一个长度为n的有序序列为止,这种排序方法称为2路归并排序。时间复杂度为O(nlogn),空间复杂度为O(n+logn),如果非递归实现归并,则避免了递归时深度为logn的栈空间空间复杂度为O(n)
六、堆排序
堆是具有下列性质的完全二叉树:每个节点的值都大于或等于其左右孩子节点的值,称为大顶堆;或者每个节点的值都小于或等于其左右孩子节点的值,称为小顶堆。堆排序就是利用堆进行排序的方法.基本思想是:将待排序的序列构造成一个大顶堆.此时,整个序列的最大值就是堆顶 的根结点.将它移走(其实就是将其与堆数组的末尾元素交换, 此时末尾元素就是最大值),然后将剩余的n-1个序列重新构造成一个堆,这样就会得到n个元素的次大值.如此反复执行,便能得到一个有序序列了。时间复杂度为 O(nlogn),好于冒泡,简单选择,直接插入的O(n^2)
七、快速排序
通过一趟排序将要排序的数据分割成独立的两部分,其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,整个排序过程可以递归进行,以此达到整个数据变成有序序列。时间复杂度为O(nlogn)
改进思路1:设置标志位,明显如果有一趟没有发生交换(flag = flase),说明排序已经完成
改进思路2:记录一轮下来标记的最后位置,下次从头部遍历到这个位置就Ok
//二分法查找
publicint binarySearch(int[] numbers,int target) {
intlow = 0;
inthigh = numbers.length-1;
while(low<=high){
intmid = (high-low)/2+low;//直接使用(high+low)/2可能导致溢出
if(numbers[mid]==target) {
returnmid;
}else{
if(numbers[mid]>target) {
high= mid-1;
}else{
low= mid+1;
}
}
}
return-1;
}