day10 【迭代器 數據結構】上課

1.Iterator迭代器(掌握)

介紹

1.Iterator是一個接口,屬於java.util包下,需要導包

2.屬於jdk1.2開始有的,之前使用迭代器Enumeration

3.Iterator在java中我們稱爲該接口是迭代器接口,專門用來迭代集合的

4.迭代:從容器(集合)中一個一個獲取數據,獲取數據之前先判斷有沒有數據,如果有數據,則獲取,如果沒有數據則不獲取,這就是迭代的思想。

使用Iterator迭代器

1.獲取迭代器接口Iterator的對象

使用集合Collection中的方法:

Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。 

說明:使用集合類的對象調用上述方法就可以獲取迭代器對象了。

2.Iterator迭代器中的方法

方法 說明
E next() 獲取集合中的元素
boolean hasNext() 判斷集合中有沒有下一個元素,如果仍有元素可以迭代,則返回 true。
void remove() 刪除當前元素
  • 代碼演示沒有這個元素異常

    package com.itheima.sh.iterator_01;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    /*
        Iterator迭代器的使用講解:
        1.獲取迭代器對象:Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。
        2.Iterator方法:
            E next()獲取集合中的元素
            boolean hasNext()判斷集合中有沒有下一個元素,如果仍有元素可以迭代,則返回 true。
     */
    public class IteratorDemo01 {
        public static void main(String[] args) {
            //1.創建集合對象
            Collection<String> coll = new ArrayList<>();
            //2.向集合中添加數據
            coll.add("柳巖");
            coll.add("馬蓉");
            coll.add("楊冪");
            coll.add("范冰冰");
            //3.根據集合對象調用方法獲取迭代器對象
            Iterator<String> it = coll.iterator();
            //4.獲取數據並輸出
            String s1 = it.next();//柳巖
            System.out.println("s1 = " + s1);
            System.out.println(it.next());//馬蓉
            System.out.println(it.next());//楊冪
            System.out.println(it.next());//范冰冰
            System.out.println(it.next());
    
        }
    }
    
    

在這裏插入圖片描述

  • 避免產生沒有這個元素異常

    package com.itheima.sh.iterator_01;
    
    import java.util.ArrayList;
    import java.util.Collection;
    import java.util.Iterator;
    
    /*
        Iterator迭代器的使用講解:
        1.獲取迭代器對象:Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。
        2.Iterator方法:
            E next()獲取集合中的元素
            boolean hasNext()判斷集合中有沒有下一個元素,如果仍有元素可以迭代,則返回 true。
     */
    public class IteratorDemo01 {
        public static void main(String[] args) {
            //1.創建集合對象
            Collection<String> coll = new ArrayList<>();
            //2.向集合中添加數據
            coll.add("柳巖");
            coll.add("馬蓉");
            coll.add("楊冪");
            coll.add("范冰冰");
            //3.根據集合對象調用方法獲取迭代器對象
            Iterator<String> it = coll.iterator();
            //4.獲取數據並輸出
           //判斷
           /* if(it.hasNext()){//it.hasNext()判斷集合中有沒有下個元素 表示條件
                String s1 = it.next();//柳巖
                System.out.println("s1 = " + s1);
            }
            System.out.println(it.next());//馬蓉
            System.out.println(it.next());//楊冪
            System.out.println(it.next());//范冰冰
            System.out.println(it.next());*/
            /*
                爲了避免沒有這個元素異常,我們在調用next()方法之前先判斷有沒有元素,如果有在獲取。這樣就可以避免上述異常
                並且上述代碼如果使用if判斷,那麼會比較重複,所以我們這裏使用循環來實現
             */
            while(it.hasNext()){//it.hasNext()表示循環條件 如果有下一個元素,則hasNext()方法返回true,沒有返回false
                //獲取數據
                String s = it.next();
                //輸出
                System.out.println("s = " + s);
            }
    
            System.out.println("coll = " + coll);
        }
    }
    
    

    小結:

    我們在調用next()方法之前,必須先調用hasNext()方法,判斷有沒有下一個元素,防止報沒有這個元素異常。代碼比較重複,我們建議使用循環替代。

3.迭代器原理

package com.itheima.sh.iterator_01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    Iterator迭代器的使用講解:
    1.獲取迭代器對象:Iterator<E> iterator() 返回在此 collection 的元素上進行迭代的迭代器。
    2.Iterator方法:
        E next()獲取集合中的元素
        boolean hasNext()判斷集合中有沒有下一個元素,如果仍有元素可以迭代,則返回 true。
 */
public class IteratorDemo02 {
    public static void main(String[] args) {
        //1.創建集合對象
        Collection<String> coll = new ArrayList<>();
        //2.向集合中添加數據
        coll.add("柳巖");
        coll.add("馬蓉");
        coll.add("楊冪");
        //3.獲取迭代器對象
        Iterator<String> it = coll.iterator();
        //4.使用循環迭代集合 itit回車自動生成while循環
        while (it.hasNext()) {
            String s =  it.next();
            System.out.println("s = " + s);
        }
    }
}

在這裏插入圖片描述

小結:

1.遊標即指針最開始在0索引位置,每次獲取數據不是根據遊標,是根據變量i獲取的

4.迭代器的問題:併發修改異常

我們使用迭代器迭代集合的時候,如果對集合長度修改(添加數據,刪除數據),不要使用集合中的方法修改,如果修改就會引發併發修改異常。

代碼演示:

package com.itheima.sh.iterator_01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    併發修改異常:
        我們使用迭代器迭代集合的時候,如果對集合**長度**修改(添加數據,刪除數據),
        不要使用集合中的方法修改,如果修改就會引發併發修改異常。
 */
public class IteratorDemo03 {
    public static void main(String[] args) {
        //1.創建集合對象
        Collection<String> coll = new ArrayList<>();
        //2.添加數據
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        //3.迭代集合
        Iterator<String> it = coll.iterator();
        while (it.hasNext()) {
            String s =  it.next();
            //需求:如果取出的數據s是bbb那麼就刪除
            //判斷s是否等於bbb
            if("bbb".equals(s)){
                //刪除s 使用集合中的刪除方法
                /*
                    這使用集合對象調用集合中的刪除方法那麼就會報併發修改異常:
                        ConcurrentModificationException
                 */
//                coll.remove(s);
                /*
                    我們可以使用Iterator迭代器中的刪除方法:void remove()
                 */
                it.remove();
            }
        }
        //打印集合coll
        System.out.println("coll = " + coll);
    }
}

小結:

1.如果使用迭代器迭代集合的時候,想刪除集合中的某個數據,千萬不要使用集合中的刪除方法,否則就會報併發修改異常ConcurrentModificationException

2.解決上述方案:使用迭代器Iterator接口中的刪除方法:void remove()即可 就不會報併發修改異常了

5.迭代器的問題:併發修改異常產生的原因和解決辦法的原因的原理(擴展,有時間看)

package com.itheima.sh.iterator_01;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    併發修改異常:
        我們使用迭代器迭代集合的時候,如果對集合**長度**修改(添加數據,刪除數據),
        不要使用集合中的方法修改,如果修改就會引發併發修改異常。
 */
public class IteratorDemo04 {
    public static void main(String[] args) {
        //1.創建集合對象
        Collection<String> coll = new ArrayList<>();
        //2.添加數據
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        coll.add("ddd");
        //3.迭代集合
        Iterator<String> it = coll.iterator();
        while (it.hasNext()) {
            String s =  it.next();
            //需求:如果取出的數據s是bbb那麼就刪除
            //判斷s是否等於bbb
            if("bbb".equals(s)){
                //刪除s 使用集合中的刪除方法
                /*
                    這使用集合對象調用集合中的刪除方法那麼就會報併發修改異常:
                        ConcurrentModificationException
                 */
//                coll.remove(s);
                /*
                    我們可以使用Iterator迭代器中的刪除方法:void remove()
                 */
                it.remove();
            }
        }
        //打印集合coll
        System.out.println("coll = " + coll);
    }
}

源碼:

public class ArrayList
{
	//獲取迭代器的方法
	public Iterator<E> iterator() {
		//創建迭代器類的對象
		return new Itr();
	}
	//成員內部類
	 private class Itr implements Iterator<E> {
		//內部類的成員位置
		//遊標 成員變量 默認值是0
		//在創建Itr類的對象時初始化值的
		//return new Itr();
		int cursor;       // index of next element to return
		int lastRet = -1; // index of last element returned; -1 if no such
		//modCount :表示集合長度的修改次數 每次修改集合該變量都會+1
		//expectedModCount 表示期望集合修改的次數
		//將集合被修改的次數賦值給期望 變量expectedModCount
		int expectedModCount = modCount;
		//成員方法
		public boolean hasNext() {
		    //cursor初始化值是0 表示遊標即指針
		    //size表示集合中的元素個數,這裏想集合添加幾個元素,size就是幾
		    //如果添加三個元素,那麼size是3
		    return cursor != size;
		}
		 //獲取集合中的數據方法
		 public E next() {
		    //檢測是否有併發修改異常的
		    checkForComodification();
		    int i = cursor;
		    if (i >= size)
			throw new NoSuchElementException();
		    Object[] elementData = ArrayList.this.elementData;
		    if (i >= elementData.length)
			throw new ConcurrentModificationException();
		    cursor = i + 1;
		    return (E) elementData[lastRet = i];
		}
	
                //檢測是否有併發修改異常的
		final void checkForComodification() {
			    //如果使用集合中的刪除方法,那麼modCount+1,而expectedModCount沒加1
			    if (modCount != expectedModCount)
				throw new ConcurrentModificationException();
			}

		//內部類Itr迭代器中的刪除方法
		public void remove() {
			.............
			//將修改後集合的次數重新賦值給期望修改的次數expectedModCount
			 expectedModCount = modCount;
			.............
		}
	 }

	//ArrayList集合中的刪除方法
	public boolean remove(Object o) {
		...................

		 fastRemove(index);
		....................
	}

	
	private void fastRemove(int index) {
	//modCount :表示集合長度的修改次數 每次修改集合該變量都會+1
        modCount++;//modCount變爲5
       .........
    }
}

小結:

1.如果使用迭代器迭代集合時,使用集合中的方法修改集合則會報併發修改異常,使用迭代器中的刪除方法就可以解決

2.發生併發修改異常的原因:在底層有一個變量modCount每次修改集合長度都會+1,還有一個變量expectedModCount表示期望修改集合的次數,剛開始創建內部類Itr對象時,執行代碼

expectedModCount = modCount

如果使用集合中的刪除方法,那麼modCount+1,但是expectedModCount並沒有改變,下次調用next()方法時,執行底層的代碼: checkForComodification();

final void checkForComodification() {
            if (modCount != expectedModCount)
                throw new ConcurrentModificationException();
        }

如果modCount和expectedModCount不相等就會報併發修改異常

3.爲什麼使用迭代器中的刪除方法不報異常呢?

因爲迭代器中的刪除方法執行了:

 expectedModCount = modCount;

將modCount修改後的值重新賦值給expectedModCount,這樣他們就會相等了,下次執行next()方法在判斷就不會報異常了

6.自學

刪除集合倒數第二個數據沒有報併發修改異常。

沒有執行next()所以沒有報異常。

2.增強for循環(掌握)

是jdk5以後誕生的技術,原理是Iterator迭代器。簡化迭代器使用的。

格式:

for(數組或者集合的數據類型 變量名:數組或者集合名){
    
}

注意:增強for循環只能用來迭代集合或者數組在迭代的時候不能對數據進行修改,否則就會報併發修改異常。

代碼演示:

package com.itheima.sh.foreach_02;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

/*
    for(數組或者集合的數據類型 變量名:數組或者集合名){

}
 */
public class ForDemo01 {
    public static void main(String[] args) {
        //調用方法
        method_2();
    }
    //迭代集合
    private static void method_2() {
        //創建集合對象
        Collection<Integer> coll = new ArrayList<>();
        //添加數據
        coll.add(10);
        coll.add(20);
        coll.add(10);
        //使用迭代器迭代集合
        /*for(Iterator<Integer> it = coll.iterator();it.hasNext();){
            //獲取數據
            Integer s = it.next();
            System.out.println("s = " + s);
        }*/
        //使用增強for循環快捷鍵:數組或者集合名.for回車
        for (Integer i : coll) {//i就是集合中的數據
            System.out.println("i = " + i);
        }
    }

    //迭代數組
    private static void method_1() {
        //定義數組
        int[] arr = {10, 20, 30};
        //使用之前學習的for循環遍歷
       /* for (int i = 0; i < arr.length; i++) {//i表示索引
            System.out.println(arr[i]);
        }*/
        //使用增強for循環遍歷數組
        for (int x : arr) {//x表示數組中的數據
            System.out.println("x = " + x);
        }
    }
}

小結:

1.增強for循環格式:

for(數組或者集合的數據類型 變量名:數組或者集合名){
    
}

2.使用增強for循環快捷鍵:數組或者集合名.for回車或者iter

3.增強for循環只能用來迭代集合或者數組在迭代的時候不能對數據進行修改,否則就會報併發修改異常。

3.泛型(掌握)

引入

1.泛型也屬於一種數據類型,但是不能單獨使用。

int a =10這個是可以的
<E> b;不可以

2.泛型格式:<標識符>這裏定義的泛型只要滿足標識符範圍即可,一般建議是大寫字母。舉例:

3.爲什麼使用泛型?

package com.itheima.sh.generic_03;

import com.sun.org.apache.xerces.internal.xs.StringList;

import java.util.ArrayList;
import java.util.Collection;

/*
    泛型引入
 */
public class Test01 {
    public static void main(String[] args) {
        //創建集合對象
        Collection<String> coll = new ArrayList<String>();
        //向集合添加數據
        coll.add("abc");
        coll.add("abcd");
//        coll.add(123);
//        coll.add(true);
        /*
            如果創建集合不使用泛型,那麼默認是Object類型,此時可以向集合中添加任意類型的數據
            如果我們知道某個需求之後,不加泛型會有問題:
            需求:求上述集合中所有字符串的長度
            問題:既然已經知道求字符串的長度了,那麼爲什麼向集合中添加數據的時候不限制只能添加字符串呢,如果不限制
            那麼添加數據可以添加任意類型,導致取出的時候還得判斷類型和強制轉換,這樣太麻煩了,有可能引發類轉換異常。
            所以我們先知道需求之後,我們可以限制集合只能存儲String類型,這裏使用泛型就可以限制
         */
        //遍歷取出每個元素並輸出長度
        //Object obj  = "abc"
        /*for (Object obj : coll) {
            //強制轉換Stirng子類
            String s =  (String) obj;
            System.out.println(s.length());
        }*/

        for (String s : coll) {
            System.out.println(s.length());
        }
    }
}

小結:

1.開發中我們都是先知道需求,根據需求操作集合。所以我們可以通過泛型來限制集合存儲的數據類型,這樣可以避免沒有必要的麻煩(強制轉換 判斷類型等)。從jdk5後,泛型已經成爲了一種開發習慣

2.泛型可以將以前運行時的錯誤變爲編譯時的錯誤

概述和注意事項

1.格式:<標識符> 定義的時候使用大寫字母

2.注意事項

  • 泛型不支持基本數據類型

     Collection<int> coll = new ArrayList<int>();錯誤的寫法
    
  • 泛型不支持繼承寫法

    Collection<Object> coll = new ArrayList<Integer>();錯誤的寫法
    
  • 從jdk7後支持如下寫法

     Collection<String> coll = new ArrayList<>();
    

自定義泛型

我們以前對於泛型都是在使用別人定義好的,我們使用。就是在集合中。我們也可以自己定義泛型。

自定義泛型有三種:

1.自定義泛型類

2.自定義泛型方法

3.自定義泛型接口

1.自定義泛型類(掌握)

格式:

public class 類名<標識符>{
    
}

代碼演示:

package com.itheima.sh.generic_04;
/*
    自定義泛型類
 */
public class Demo<ABC> {
    //成員變量
    int age;
    ABC name;//這裏還不知道ABC的具體數據類型
    //定義成員方法
    public void show(ABC name){
        this.name = name;
        System.out.println("name = " + this.name);
    }
}

package com.itheima.sh.generic_04;

import java.util.ArrayList;

public class Test01 {
    public static void main(String[] args) {
        //創建對象
        Demo<String> d = new Demo<>();
        //使用對象d調用show方法
        d.show("鎖哥");
        //再次創建對象
        Demo<Integer> d1 = new Demo<>();
        d1.show(10);

        Demo d2 = new Demo();
        d2.show(true);
    }
}

小結:

1.自定義泛型類格式:

public class 類名<標識符>{
    
}

2.自定義泛型類何時確定泛型?

在創建對象時確定,如果創建對象不指定泛型的具體數據類型,那麼就是Object

 Demo<String> d = new Demo<>();

2.自定義泛型方法(掌握)

格式:

方法修飾符 <標識符> 方法返回值類型 方法名(參數列表){
    
}
說明:
    1. <標識符>表示定義的泛型

代碼演示:

package com.itheima.sh.generic_05;
/*
    自定義泛型類
 */
public class Demo<ABC> {
    //成員變量
    int age;
    ABC name;//這裏還不知道ABC的具體數據類型
    //定義成員方法
    public void show(ABC name){
        this.name = name;
        System.out.println("name = " + this.name);
    }

    /*
        自定義泛型方法:
        方法修飾符 <標識符> 方法返回值類型 方法名(參數列表){

        }
        說明:
            1. <標識符>表示定義的泛型
     */
    //1.<IT>定義泛型  2.IT it 使用泛型IT
    public <IT> void method(IT it){
        System.out.println("it = " + it);
    }
}

package com.itheima.sh.generic_05;

public class Test01 {
    public static void main(String[] args) {
        //創建對象
        Demo<String> d = new Demo<>();
        //使用對象調用方法
        d.method(10);
        d.method(true);
    }
}

小結:

1.自定義泛型方法是在調用方法時確定泛型

2.格式:

方法修飾符 <標識符> 方法返回值類型 方法名(參數列表){

}

3.自定義泛型接口(掌握)

格式:

public interface 接口名<標識符>{
    
}

代碼演示:

public interface Inter<T> {
    //定義抽象方法
    void show(T t);
}

package com.itheima.sh.generic_06;
/*
    接口的泛型確定具體的數據類型由兩種方式:
    1.是實現類實現接口時確定
     public class InterImpl implements Inter<String>{}
    2.泛型的傳遞
    public interface Inter<T> {}
    public class InterImpl<E> implements Inter<E>{}
    InterImpl<Integer> ip = new InterImpl<>();//創建對象時確定自定義泛型類的數據類型

    補充:集合使用的就是泛型傳遞的方式確定泛型的具體數據類型
    public interface Collection<E>{}
    public interface List<E> extends Collection<E> {}
    public class ArrayList<E> implements List<E>{}
    ArrayList<String> list = new ArrayList<String>();
 */
//public class InterImpl implements Inter<String>{
public class InterImpl<E> implements Inter<E>{

    @Override
    public void show(E e) {
        System.out.println(e);
    }
}

package com.itheima.sh.generic_06;

public class Test01 {
    public static void main(String[] args) {
        //創建實現類對象
       /* InterImpl ip = new InterImpl();
        ip.show("abc");*/
        //創建實現類對象
        InterImpl<Integer> ip = new InterImpl<>();
        ip.show(10);
    }
}

小結:

1.自定義泛型接口格式:

public interface 接口名<標識符>{
    
}

2.何時確定泛型接口的具體的數據類型?

1)是實現類實現接口時確定

     public class InterImpl implements Inter<String>{}

2)泛型的傳遞

 public interface Collection<E>{}
    public interface List<E> extends Collection<E> {}
    public class ArrayList<E> implements List<E>{}
    ArrayList<String> list = new ArrayList<String>();

總結:

  • 自定義泛型類是在創建對象時確定具體的數據類型
  • 自定義泛型方法是在調用方法時確定數據類型
  • 自定義泛型接口:
    • 實現類實現接口時確定
    • 泛型傳遞確定

泛型通配符和限定(掌握)

  • 泛型通配符符號是:使用問號**?**表示泛型通配符
package com.itheima.sh.generic_07;

import java.util.ArrayList;
import java.util.Collection;

/*
    泛型通配符
 */
public class Test01 {
    public static void main(String[] args) {
        //創建集合對象
        Collection<String> coll = new ArrayList<>();
        coll.add("aaa");
        coll.add("bbb");
        coll.add("ccc");
        Collection<Integer> coll2 = new ArrayList<>();
        coll2.add(10);
        coll2.add(20);
        //調用自定義方法打印上述兩個集合內容
        printColl(coll);
        printColl(coll2);
    }
    /*
        Collection<Object> coll = new ArrayList<String>(); 錯誤寫法
        Collection<Object> coll = new ArrayList<Integer>();錯誤寫法
        注意:我們希望傳遞的泛型是String類型,那麼下面方法接收到類型就是String
        注意:我們希望傳遞的泛型是Integer類型,那麼下面方法接收到類型就是Integer
        對於這種問題我們可以使用自定義泛型方法來解決,調用方法時確定數據類型
        這裏我們還可以使用泛型通配符解決: ?

         Collection<?> coll = new ArrayList<String>();
         Collection<?> coll = new ArrayList<Integer>();
     */
//    private static <T> void printColl(Collection<T> coll) {
    private static  void printColl(Collection<?> coll) {
        //遍歷集合
        for (Object o : coll) {
            System.out.println(o);
        }
    }
}

  • 泛型限定

    • 上限限定:? extends E 這裏的?可以是E類型本身以及子類類型

      ? extends Person?通配符的類型可以是Person,或者Person的子類
      

      代碼演示:

      package com.itheima.sh.generic_07;
      
      public class Person {
      }
      
      package com.itheima.sh.generic_07;
      
      public class Student extends Person {
      }
      
      
      package com.itheima.sh.generic_07;
      
      import java.util.ArrayList;
      
      /*
          上限限定:? extends E  這裏的?可以是E類型本身以及子類類型
              舉例:? extends Person :?通配符的類型可以是Person,或者Person的子類
       */
      public class Test02 {
          public static void main(String[] args) {
              //創建集合
              ArrayList<Person> list = new ArrayList<>();
              ArrayList<Student> list2 = new ArrayList<>();
              //調用方法打印集合
              printList(list);
              printList(list2);
          }
      
          private static void printList(ArrayList<? extends Person> list) {
          }
      }
      
      
    • 下限限定:? super E 那麼通配符?的數據類型可以是E本身以及父類

      舉例:
          ? super Student:  ?的類型是Student或者Student的父類
      
      package com.itheima.sh.generic_07;
      
      import java.util.ArrayList;
      
      /*
          下限限定:? super E  那麼通配符?的數據類型可以是E本身以及父類
              舉例:
             ? super Student:  ?的類型是Student或者Student的父類
       */
      public class Test03 {
          public static void main(String[] args) {
              //創建集合
              ArrayList<Person> list = new ArrayList<>();
              ArrayList<Student> list2 = new ArrayList<>();
              //調用方法打印集合
              printList(list);
              printList(list2);
          }
      
          private static void printList(ArrayList<? super Student> list) {
          }
      }
      
      

      小結:

      1.通配符使用?表示

      2.泛型上限限定:? extends Person ?可以是Person以及子類

      3.泛型下限限定:? super Student ?可以是Student以及父類

4.數據結構(掌握)

概念介紹

就是存儲數據的方式,不同的數據結構存儲數據的特點是不一樣。

數據結構包括:鏈表 數組 樹 堆棧 隊列。。。

棧數據結構

英文是stack,又稱堆棧,它是運算受限的線性表,其限制是僅允許一端進行插入和刪除操作,不允許在其他任何位置進行添加、查找、刪除等操作。

舉例:類似於生活中子彈彈夾。放子彈和打出子彈都是一端。

在這裏插入圖片描述

小結:

1.堆棧數據結構只能一端進和出

2.特點:先進後出

3.這裏兩個名詞需要注意:

  • 壓棧:就是存元素。即,把元素存儲到棧的頂端位置,棧中已有元素依次向棧底方向移動一個位置。
  • 彈棧:就是取元素。即,把棧的頂端位置元素取出,棧中已有元素依次向棧頂方向移動一個位置。

隊列數據結構

也是受限制的數據結構,只允許一端進,另一端出。

特點:先進先出。類似於生活中排隊買票,火車進山洞等

在這裏插入圖片描述

小結:

1.也是受限制的數據結構,只允許一端進,另一端出。

2.特點:先進先出。

數組數據結構

在內存中一串連續的空間,類似於生活中的監獄。樓房,火車車廂 。

特點:查詢快,增刪慢。

在這裏插入圖片描述

小結:

1.數組在內存中是開闢連續的的空間

2.數組數據結構特點:查詢快,增刪慢。ArrayList 底層就是數組數據結構,查詢使用,增刪不建議使用。

鏈表數據結構

我們後續學習的集合LinkedList底層是雙鏈表數據結構。鏈表數據結構有兩種:

  • ​ 單向鏈表
  • ​ 雙向鏈表

**鏈表:**鏈表由多個節點組成。然後由一個鏈子將多個節點連接起來。

節點:每個節點由多部分組成,一部分用來存儲數據的稱爲數據域,其他部分用來存儲其他節點的地址值的,稱爲指針域。

在這裏插入圖片描述

小結:鏈表數據結構查詢慢,增刪快。後期學習的LKinkedList底層是鏈表數結構,開發時只要增刪使用LinkedList

樹基本結構介紹

概念介紹:

計算機中的樹數據結構是生活中倒立的樹。就是在計算機中樹根在上面。

名詞解釋:

名詞 含義
節點 指樹中的一個元素(數據)
節點的度 節點擁有的子樹(兒子節點)的個數,二叉樹的度不大於2,例如:下面二叉樹A節點的度是2,E節點的度是1,F節點的度是0
葉子節點 度爲0的節點,也稱之爲終端結點,就是沒有兒子的節點。
高度 葉子結點的高度爲1,葉子結點的父節點高度爲2,以此類推,根節點的高度最高。例如下面二叉樹ACF的高度是3,ACEJ的高度是4,ABDHI的高度是5.
根節點在第一層,以此類推
父節點 若一個節點含有子節點,則這個節點稱之爲其子節點的父節點
子節點 子節點是父節點的下一層節點
兄弟節點 擁有共同父節點的節點互稱爲兄弟節點

在這裏插入圖片描述

二叉查找樹

1. 【左子樹】上所有的節點的值均【小於】他的【根節點】的值 
2. 【右子樹】上所有的節點值均【大於】他的【根節點】的值 
3. 每一個子節點最多有兩個子樹
4. 二叉查找樹中沒有相同的元素

在這裏插入圖片描述

平衡二叉樹

爲了提高查找效率的。

規則:它的左右兩個子樹的高度差的絕對值不超過1,並且左右兩個子樹都是一棵平衡二叉樹

在這裏插入圖片描述

小結:平衡二叉樹查找效率高於非平衡二叉樹。

總結:

二叉樹:每個節點的子節點不超過2個

二叉查找樹:

​ 1)左子樹小於根節點,右子樹大於根節點

​ 2)沒有相等的數據

平衡二叉樹:每個節點的左右子樹的度的絕對值不能超過1.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章