1 链表
链表通常是由一连串的结点组成,每一个节点包含任意的实例数据和一个或两个用来指向上一个或下一个节点位置的链接
链表是一种线性表,但是并不会按照线性的顺序存储数据,而在每一个结点里存放下一个节点的指针
1.1 分类
单向链表 : 一个单链表的节点分为两部分,第一部分保存节点的数据,第二部分保存下一个结点的地址,最后一个节点存储地址的部分指向空值
public class SingleLinkedList {
private int size;
private Node head;
public SingleLinkedList(){
size = 0;
head= null;
}
private class Node{
private Object data;
private Node next;
public Node(Object data){
this.data = data;
}
}
public Object addHead(Object data){
Node newHead = new Node(data);
if(size == 0 ){
head = newHead;
}else{
newHead.next = head;
head = newHead;
}
size++;
return data;
}
public Object deleteHead(){
Object obj = head.data;
head = head.next;
size--;
return obj;
}
public Node find(Object data){
Node current = head;
int tempSize = size;
while(tempSize > 0 ){
if(data.equals(current.data)){
return current;
}else{
current = current.next;
}
tempSize--;
}
return null;
}
public boolean delete(Object data){
if(size == 0 ){
return false;
}
Node current = head;
Node previous = head;
while(!current.data.equals(data)){
if (current.next == null){
return false;
}else{
previous = current;
current = current.next;
}
}
if(current == head){
head = current.next;
size--;
}else{
previous.next =current.next;
size--;
}
return true;
}
public boolean isEmpty(){
return size==0;
}
public void display(){
if(size > 0 ){
Node node = head;
int tempSize = size;
if(tempSize == 1){
System.out.println("[" + node.data+"]");
return;
}
while(tempSize >0 ){
if(node.equals(head)){
System.out.print("[" + node.data+"->");
}else if(node.next == null){
System.out.print( node.data+"]");
}else{
System.out.print(node.data+"->");
}
node= node.next;
tempSize--;
}
System.out.println();
}else{
System.out.println("[]");
}
}
}
1.2 栈 队列 链表 的区别
栈 队列是线性表 操作受限 区别 在于运算规则不同 链表和数组:
- 占用的内存空间 链表存放的空间可以是连续的,也可以是不连续的,数组一定是连续的。
- 长度的可变性 ,链表的长度可根据需要自定伸缩 ,数组长度一旦定义就不能更改
- 数据的访问,链表需要移动访问,不便 数组方便更加便捷
- 使用场景
数据量大而且需要进行频繁访问元素,数组更合适 删除 插入等操作链表更加合适
链表的特点: 逻辑结构 一对一 存储结果 顺序表 链表 运算规则:随机 顺序存放 栈 逻辑结构 一对一 存储结果 顺序栈 链栈 运算规则:先进后出 后进先出 队列 逻辑结构 一对一 存储结果 顺序队 链队 运算规则:先进先出 后进后出
双向链表 循环链表
2 非线性结构(树结构)
2.1 二叉树
每一个元素称为节点 | A—根节点 | B C D----父节点 | H E F G-----叶子节点 叶子节点:没有字节的节点 树的高度: 最大的层数
森林 多棵子树构成森林
每个结点最多只有两个子节点的形式的树称为二叉树
如果所有的二叉树的叶子结点都在最后一次。节点数 = 2^n - 1 , n就是他的层数 将这样的二叉树称为满二叉树
2.2 二叉树的遍历
前序遍历:先输出父节点 再遍历左子树和右子树
中序遍历:先遍历左子树 在输出父节点 最后遍历右子树
后序遍历:先遍历左子树 再遍历右子树 最后输出父节点
层序遍历:按照层级逐层遍历
2.3 红黑树
红黑树是一种含有红黑结点并能自平衡的二叉树。他必须满足一下的性质:
1 每个结点要么是黑色 要么是红色
2 根节点是黑色
3 每个叶子结点是NIL是黑色
4 每个红色结点的两个子节点一定是黑色
5 任意一个结点到叶子结点的路径都包含数量相同的黑结点
3 集合
数组本身存在一些不可避免地弊端
数组在存储方面的特点:
- 初始化以后长度确定,不可改变
- 数组生命的类型就决定了进行元素初始化时地类型
弊端:
- 初始化之后 长度不可改变 不便于拓展
- 数组中提供的属性和方法较少,不便于对元素的添加删除从插入等操做,且效率不高,同时无法直接获取存储元素地个数
- 数组存储的数据是有序的,可以重复
Java 针对存储提供了一种新得结构----集合,可以把动态地把多个对象引用放入到容器中 Java集合可以存储数量不等的多个对象,还可以保存具有映射关系的数据
3.1 集合地体系结构
集合的特点 提供一种存储空间可变的存储模型,存储的数据的容量可随时发生改变
public interface Collection<E> extends Iterable<E>
集合层次结构中的跟接口,只能存储对象,而其他集合不允许。有的集合石有序的,而有些集合是无序的。JDK不提供此接口的任何直接实现:它提供了更具体的子接口的实现,如Set和List 。 该接口通常用于传递集合,并在需要最大的通用性的情况下对其进行操作。(多态性)
3.2 Collection 接口的使用
Collection 是单列集合的顶层接口,表示一组对象,这些对象也称为元素
JDK不提供此接口的直接实现 但是可以通过的子接口的实现来创建集合对象
boolean | add(E e) 确保此集合包含指定的元素(可选操作)。 |
---|
boolean | addAll(Collection<? extends E> c) 将指定集合中的所有元素添加到此集合(可选操作)。 | void | clear() 从此集合中删除所有元素(可选操作)。 | boolean | contains(Object o) 如果此集合包含指定的元素,则返回 true 。 | boolean | containsAll(Collection<?> c) 如果此集合包含指定 集合 中的所有元素,则返回true。 | boolean | equals(Object o) 将指定的对象与此集合进行比较以获得相等性。 | int | hashCode() 返回此集合的哈希码值。 | boolean | isEmpty() 如果此集合不包含元素,则返回 true 。 | Iterator<E> | iterator() 返回此集合中的元素的迭代器。 | boolean | remove(Object o) 从该集合中删除指定元素的单个实例(如果存在)(可选操作)。 | boolean | removeAll(Collection<?> c) 删除指定集合中包含的所有此集合的元素(可选操作)。 | boolean | retainAll(Collection<?> c) 仅保留此集合中包含在指定集合中的元素(可选操作)。 | int | size() 返回此集合中的元素数。 | Object[] | toArray() 返回一个包含此集合中所有元素的数组。 | <T> T[] | toArray(T[] a) 返回包含此集合中所有元素的数组; 返回的数组的运行时类型是指定数组的运行时类型。 |
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("Hello");
collection.add(123);
collection.add(true);
System.out.println(collection);
}
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("Hello");
collection.add(123);
collection.add(true);
System.out.println(collection.contains(123));
System.out.println(collection.remove(123));
System.out.println(collection.isEmpty());
System.out.println(collection.size());
Object[] arr = collection.toArray();
System.out.println(arr.length);
System.out.println(collection);
}
public class CollectionTest {
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("Hello");
collection.add(123);
collection.add(true);
Collection c1 = new ArrayList();
c1.add("world");
c1.add("hello");
c1.add(false);
Student stu1 = new Student("张三",18);
c1.add(stu1);
collection.addAll(c1);
System.out.println(collection);
System.out.println(collection.containsAll(c1));
collection.retainAll(c1);
System.out.println(collection);
}
3.2.1 Iterator
迭代集合的迭代器
boolean | hasNext() 如果迭代具有更多元素,则返回 true 。 |
---|
| `E` | `next()` 返回迭代中的下一个元素。 |
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("Hello");
collection.add(123);
collection.add(true);
collection.add("world");
collection.add("hello");
collection.add(false);
Student stu1 = new Student("张三",18);
collection.add(stu1);
Iterator iter = collection.iterator();
while(iter.hasNext()){
Object obj = iter.next();
System.out.println(obj);
}
}
public static void main(String[] args) {
Collection collection = new ArrayList();
collection.add("Hello");
collection.add(123);
collection.add(true);
collection.add("world");
collection.add("hello");
collection.add(false);
Student stu1 = new Student("张三",18);
collection.add(stu1);
Iterator iter = collection.iterator();
while(iter.hasNext()){
Object obj = iter.next();
System.out.println(obj);
}
}
3.3 List
3.3.1 List集合的特点
3.3.2 List接口特有方法
add(int index, Object element) 将指定的元素插入此列表中的指定位置(可选操作)。
Object | get(int index) 返回此列表中指定位置的元素。 |
---|
int | indexOf(Object o) 返回此列表中指定元素的第一次出现的索引,如果此列表不包含元素,则返回-1。 | int | lastIndexOf(Object o) 返回此列表中指定元素的最后一次出现的索引,如果此列表不包含元素,则返回-1。 | ListIterator<E> | listIterator() 返回列表中的列表迭代器(按适当的顺序)。 | E | set(int index, E element) 用指定的元素(可选操作)替换此列表中指定位置的元素。 | List<E> | subList(int fromIndex, int toIndex) 返回此列表中指定的 fromIndex (含)和 toIndex 之间的视图。 |
3.3.3. List的使用
public class ListTest {
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",21);
Student stu3 = new Student("王五",20);
Student stu4 = new Student("赵六",22);
List list = new ArrayList();
list.add(stu4);
list.add(stu3);
list.add(stu2);
list.add(stu1);
list.add(stu1);
list.add(stu2);
list.add(stu3);
list.add(stu4);
Iterator iter = list.iterator();
while(iter.hasNext()){
Object obj = iter.next();
System.out.println(obj);
}
System.out.println("------------------------------");
for(int i = 0 ; i < list.size();i++){
Object obj = list.get(i);
System.out.println(obj);
}
}
}
List集合的有序:这里的有序指的是元素的存入顺序和迭代的顺序是一致的
集合的迭代方式
public static void main(String[] args) {
Student stu1 = new Student("张三",18);
Student stu2 = new Student("李四",21);
Student stu3 = new Student("王五",20);
Student stu4 = new Student("赵六",22);
List list = new ArrayList();
list.add(stu4);
list.add(stu3);
list.add(stu2);
list.add(stu1);
list.add(stu1);
list.add(stu2);
list.add(stu3);
list.add(stu4);
Iterator iter = list.iterator();
while(iter.hasNext()){
Object obj = iter.next();
System.out.println(obj);
}
System.out.println("------------------------------");
for(int i = 0 ; i < list.size();i++){
Object obj = list.get(i);
System.out.println(obj);
}
System.out.println("------------------------------");
for(Object obj : list){
System.out.println(obj);
}
System.out.println("------------------------------");
for( Iterator itr = list.iterator();itr.hasNext();){
Object obj = itr.next();
System.out.println(obj);
}
System.out.println("------------------------------");
Iterator itr1 = list.iterator();
for(;itr1.hasNext();){
Object obj = itr1.next();
System.out.println(obj);
}
}
迭代器使用while和for那个更好:
- for循环更利于空间的释放 但是在开发中 普遍使用while
3.3.4 并发修改异常
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
Iterator iter = list.iterator();
while(iter.hasNext()){
Object obj = iter.next();
String str = (String) obj;
if(str.equals("world")){
list.add("hadoop");
}
}
}
ConcurrentModificationException : 并发修改异常
产生原因:
? 迭代器在迭代集合的过程中,通过集合对象修改了集合的元素,造成迭代器获取园中判断预期修改值和实际修改值不一致
解决方案:通过集合本身来进行遍历集合,有集合自己修改
for(int i = 0 ; i < list.size();i++){
String str = (String)list.get(i);
if(str.equals("world")){
list.set(i,"hadoop");
}
}
System.out.println(list);
3.3.5 ListIteator
void | add(E e) 将指定的元素插入列表(可选操作)。 |
---|
boolean | hasNext() 返回 true 如果遍历正向列表,列表迭代器有多个元素。 | boolean | hasPrevious() 返回 true 如果遍历反向列表,列表迭代器有多个元素。 | E | next() 返回列表中的下一个元素,并且前进光标位置。 | int | nextIndex() 返回随后调用 next() 返回的元素的索引。 | E | previous() 返回列表中的上一个元素,并向后移动光标位置。 | int | previousIndex() 返回由后续调用 previous() 返回的元素的索引。 | void | remove() 从列表中删除由 next() 或 previous() 返回的最后一个元素(可选操作)。 | void | set(E e) 用 指定的元素替换由 next() 或 previous() 返回的最后一个元素(可选操作)。 |
public class ListDemo {
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator iterator = list.listIterator();
while(iterator.hasNext()){
Object obj = iterator.next();
if(obj.equals("world")){
iterator.add("spring");
iterator.previous();
}
System.out.println(obj);
}
System.out.println(list);
System.out.println("-----------------------");
ListIterator iterator1 = list.listIterator();
while(iterator1.hasNext()){
Object obj = iterator1.next();
if(obj.equals("world")){
iterator1.remove();
}else{
System.out.println(obj);
}
}
System.out.println("-----------------------");
ListIterator iterator2 = list.listIterator();
while(iterator2.hasNext()){
Object obj = iterator2.next();
if(obj.equals("hello")){
iterator2.set("mybatis");
iterator2.previous();
}else{
System.out.println(obj);
}
}
}
}
public static void main(String[] args) {
List list = new ArrayList();
list.add("hello");
list.add("world");
list.add("java");
ListIterator iter = list.listIterator();
while(iter.hasNext()){
Object obj = iter.next();
System.out.println(obj);
}
System.out.println("----------------------");
while(iter.hasPrevious()){
Object obj = iter.previous();
System.out.println(obj);
}
}
List sub = list.subList(1,2);
System.out.println(sub);
|