基本数据结构:
- 数组、多维数组、字符串、队列(双向队列)、栈、链表(双链表)、堆(优先队列)、哈希表(字典)、集合、二叉树、排序、容器类
数组与多维数组
-
创建数组
// 数组与多维数组 int[] arr = new int[10]; int[] arr2 = new int[]{ 1, 5, 13, 4, 7}; int[] arr3 = { 1, 2, 3, 4}; int[][] a = new int[3][4]; int[][] b = new int[][]{ { 11,12,13,14},{ 21,22,23,24},{ 31,32,33,34}};
-
数组类Arrays的常用方法
-
binarySearch(float[] a, int fromIndex, int toIndex, float key)
使用二分搜索算法搜索指定数组的浮点数范围。 不给范围即全范围搜索。 -
equals(int[] a, int[] a2)
如果两个指定的int数组彼此 相等 ,则返回 true 。 顺序与值一致即为true。 -
fill(int[] a, int fromIndex, int toIndex, int val)
将指定的int值分配给指定的int数组的指定范围的每个元素。 不指定范围即全范围。 -
sort(int[] a, int fromIndex, int toIndex)
按升序排列数组的指定范围。 不指定范围即全范围。 -
toString(int[] a)
返回指定数组的内容的字符串表示形式。@Test public void array1() { int[] arr2 = new int[]{ 1, 5, 13, 4, 7}; int[] arr1 = { 1, 5, 13, 4, 7}; int res1 = Arrays.binarySearch(arr2, 13); boolean res2 = Arrays.equals(arr1, arr2); Arrays.sort(arr1); System.out.println(res1); System.out.println(res2); System.out.println(Arrays.toString(arr1)); Arrays.fill(arr1,0,2,99); System.out.println(Arrays.toString(arr1)); }
-
-
动态数组 — ArrayList
-
add(E e)
将指定的元素追加到此列表的末尾。 -
add(int index, E element)
在此列表中的指定位置插入指定的元素。 -
clear()
从列表中删除所有元素。 -
clone()
返回此 ArrayList实例的浅拷贝。 -
contains(Object o)
如果此列表包含指定的元素,则返回 true 。 -
get(int index)
返回此列表中指定位置的元素。 -
indexOf(Object o)
返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 -
isEmpty()
如果此列表不包含元素,则返回 true 。 -
lastIndexOf(Object o)
返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 -
remove(int index)
删除该列表中指定位置的元素。 -
set(int index, E element)
用指定的元素替换此列表中指定位置的元素。 -
size()
返回此列表中的元素数。 -
sort(Comparator<? super E> c)
使用提供的 Comparator对此列表进行排序以比较元素。 -
toArray()
以正确的顺序(从第一个到最后一个元素)返回一个包含此列表中所有元素的数组。
@Test public void arrlist(){ ArrayList<Integer> list = new ArrayList<Integer>(); //泛型要使用引用类型不能是基本数据类型,首字母大写即可提示 list.add(1);list.add(9);list.add(3);list.add(9); list.add(2,99);//添加元素,将元素插到任意位置 list.set(1,6); //修改下标1的元素值为6 list.remove(3);//移除下标3的元素 int len = list.size(); int res = list.get(1);// 等价于a[1] Collections.sort(list); for(int i:list){ System.out.println(i); } ArrayList<Integer> list2 = (ArrayList<Integer>) list.clone(); //克隆一份 list2.clear(); //清空元素 boolean con = list.contains(3); //判断是否包含 list.indexOf(1); //返回元素1的索引值 boolean emp = list.isEmpty(); //判断是否为空 Object[] arr = list.toArray(); //转换成数组 int last = list.lastIndexOf(6); //指定元素最后出现的位置索引 Collections.reverse(list); //翻转数组 Collections.swap(list,0,1); //交换元素 System.out.println(list); Integer max = Collections.max(list); //最大值 Integer min = Collections.min(list); //最小值 System.out.println("max: "+max+" min:"+min); }
-
字符串 — StringBuffer
-
append(sth)
sth 可以是基本数据类型,也可以是字符串类型,也可以字符数组,也可以是StringBuffer
-
capacity()
返回当前容量。 不是当前字符的个数,而是容器的容量。 -
length()
返回长度(字符数)。 -
charAt(int index)
返回 char在指定索引在这个序列值。 -
delete(int start, int end)
删除此序列的子字符串中的字符。 -
deleteCharAt(int index)
删除 char在这个序列中的指定位置。 -
indexOf(String str)
返回指定子字符串第一次出现的字符串内的索引。 -
indexOf(String str, int fromIndex)
返回指定子串的第一次出现的字符串中的索引,从指定的索引开始。 -
insert(int offset, char c)
在此序列中插入 char参数的字符串表示形式。 其中后一项char 可以是基本数据类型、char数组、String等。 -
insert(int index, char[] str, int offset, int len)
在此序列中插入 str数组参数的子阵列的字符串表示形式。 -
lastIndexOf(String str)
返回指定子字符串最右边出现的字符串内的索引。 -
replace(int start, int end, String str)
用指定的String中的字符替换此序列的子字符串中的 String 。 -
reverse()
导致该字符序列被序列的相反代替。 -
setCharAt(int index, char ch)
指定索引处的字符设置为 ch 。 -
substring(int start, int end)
返回一个新的 String ,其中包含此序列中当前包含的字符的子序列。 -
toString()
返回表示此顺序中的数据的字符串。注意,以上如方法果对原来的
StringBuffer
操作后返回的还是StringBuffer
对象,那么可以不用返回值,因为返回值(引用)指向还是原来的StringBuffer
的内存,是在原来的数据上进行操作。
@Test
public void my_stringbf(){
StringBuffer sb = new StringBuffer();
sb.append(123).append('c').append(737.23112).append(true).append(new char[]{
'_','n','c','d'},0,3);
// 123c737.23112true_nc
sb.append(sb);
// 123c737.23112true_nc123c737.23112true_nc
System.out.println(sb);
System.out.println(sb.capacity());
sb.delete(0,sb.length()); //删除字符串
System.out.println("sb:"+sb);
sb.append("abcdefgbcdbcd");
char c = sb.charAt(0);
StringBuffer sb2 = sb.deleteCharAt(0);//可以不用接住返回值
int first_idx = sb.indexOf("bcd");
int second_idx = sb.indexOf("bcd",3);
StringBuffer sb3 = sb.insert(0, "AAA"); //可以不用接住返回值
int last_idx = sb.lastIndexOf("bcd");
StringBuffer sb4 = sb.replace(0, 4, "GGGGGG");//可以不用接住返回值
StringBuffer rev = sb.reverse();//可以不用接住返回值
sb.setCharAt(0,'A');
CharSequence sub = sb.subSequence(3, 5);
//Note:注意,以上sb、sb2、sb3、sb4 都指向sb内存,实际上是共享数据
}
队列、双向队列、栈 — ArrayDeque
使用双向队列ArrayDeque可以完成以上三种数据结构。队列的操作包括:入队、出队、返回队首元素、返回队尾元素、删除队首元素、删除队尾元素、判断空、返回队列长度。双向队列包括:首尾入队、首尾出队、返回首尾元素、删除首尾元素、判断空、返回队列长度。栈包括:入栈、出栈、返回栈顶元素、返回栈尾元素、判断空,返回栈长度。
双向队列:
-
addFirst(E e)
在此deque前面插入指定的元素。 -
addLast(E e)
在此deque的末尾插入指定的元素。 -
getFirst()
检索,但不删除,这个deque的第一个元素。 如果此deque为空,则报错。 -
getLast()
检索,但不删除,这个deque的最后一个元素。 如果此deque为空,则报错。 -
removeFirst()
检索并删除此deque的第一个元素。 如果此deque为空,则报错。 -
removeLast()
检索并删除此deque的最后一个元素。 如果此deque为空,则报错。 -
size()
返回此deque中的元素数。 -
contains(Object o)
如果此deque包含指定的元素,则返回 true 。 -
clear()
从这个deque中删除所有的元素。
@Test
public void my_queue(){
ArrayDeque<Integer> arrdeq = new ArrayDeque<>();
arrdeq.add(3);
arrdeq.add(9);
arrdeq.add(0);
arrdeq.addFirst(1);
arrdeq.addLast(2);
boolean con = arrdeq.contains(9);
Integer peekf = arrdeq.peekFirst(); //返回队头元素,如果此deque为空,则报错。
Integer peekl = arrdeq.peekLast();//返回队尾元素,如果此deque为空,则报错。
Integer pf = arrdeq.pollFirst();//队头元素出队并返回,如果此deque为空,则报错。
Integer pl = arrdeq.pollLast();//队尾元素出队并返回,如果此deque为空,则报错。
boolean empty = arrdeq.isEmpty();
arrdeq.clear();
}
Note: 只要掌握了上面的双向队列的操作,那么栈和队列的操作也就会了。注意,最好使用如果队列为空报错的操作而不使用返回null的操作,因为,为空报错对于算法是好的,而返回null有时候很难发现错误!
堆(优先队列)— PriorityQueue
-
add(E e)
将指定的元素插入到此优先级队列中。 -
peek()
检索但不删除此队列的头,如果此队列为空,则返回 null 。 -
poll()
检索并删除此队列的头,如果此队列为空,则返回 null 。 -
remove(Object o)
从该队列中删除指定元素的单个实例(如果存在)。 -
size()
返回此集合中的元素数。 -
toArray()
返回一个包含此队列中所有元素的数组。 -
contains(Object o)
如果此队列包含指定的元素,则返回 true 。
@Test
public void my_priorityQueue(){
// 默认小根堆,如果要大根堆,只需要乘以-1即可,然后结果再恢复
PriorityQueue<Integer> pq = new PriorityQueue<Integer>();
pq.add(9);
pq.add(1);
pq.add(4);
Integer peek = pq.peek();
Integer poll = pq.poll();
boolean res = pq.remove(1);
}
哈希表(字典)— HashMap
-
put(K key, V value)
将指定的值与此映射中的指定键相关联。 -
get(Object key)
返回到指定键所映射的值,或 null如果此映射包含该键的映射。 -
isEmpty()
如果此map不包含键值映射,则返回 true 。 -
keySet()
返回此map中包含的键的Set视图。 -
remove(Object key)
从该map中删除指定键的映射(如果存在)。 -
replace(K key, V value)
只有当目标映射到某个值时,才能替换指定键的条目。 -
values()
返回此map中包含的值的Collection视图。 -
size()
返回此map中键值映射的数量。
@Test
public void my_hash(){
HashMap<String, Integer> hash = new HashMap<>();
hash.put("aaa",120);
hash.put("bbb",110);
hash.put("ccc",119);
Set<String> keys = hash.keySet();
Collection<Integer> values = hash.values();
hash.put("aaa",114); //可以替换成功
hash.replace("aaa",999); //可以替换成功
hash.remove("aaa");
}
集合—HashSet
-
add(E e)
将指定的元素添加到此集合(如果尚未存在)。 -
contains(Object o)
如果此集合包含指定的元素,则返回 true 。 -
isEmpty()
如果此集合不包含元素,则返回 true 。 -
remove(Object o)
如果存在,则从该集合中删除指定的元素。 -
size()
返回此集合中的元素数(其基数)。 -
clear()
从此集合中删除所有元素。
@Test
public void my_set(){
HashSet<Integer> set = new HashSet<>();
set.add(3);
set.add(5);
set.add(8);
set.add(3);
set.remove(3);
boolean res = set.contains(3);
}
二叉树
public class TreeNode {
public char val;
public TreeNode left;
public TreeNode right;
public TreeNode(char val){
this.val = val;
}
}
@Test
public void my_tree(){
TreeNode root = new TreeNode('a');
root.left = new TreeNode('b');
root.right = new TreeNode('c');
}