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.