寫在前面:
數組和鏈表是數據結構中最基礎的兩種結構,其他的都是由這兩者轉化而來;
因此,掌握這兩種結構至關重要!下面,時光就帶大家來學習一下數組和鏈表;
思維導圖:
1,什么是線性表?
線性表是具有相同類型的n(>=0)個數據元素的有限序列(a0,a1,a2,…,an),ai是表項,n是表長度;
那么為什么要提到線性表呢?
因為數組和鏈表都是線性表的結構,只不過它們的存儲方式不一樣;
根據存儲方式不同,可將線性表分為順序表和鏈式表;
線性表是數據結構中的邏輯結構。可以存儲在數組上,也可以存儲在鏈表上。
一句話,用數組來存儲的線性表就是順序表。
2,數組和鏈表
數組:在內存中,是一塊連續的內存區域;
鏈表:是由不連續的內存空間組成;
3,數組和鏈表的區別
數組優點: 隨機訪問性強,查找速度快(連續內存空間導致的);
數組缺點: 插入和刪除效率低 可能浪費內存 內存空間要求高,必須有足夠的連續內存空間。數組大小固定,不能動態拓展鏈表的優點: 插入刪除速度快 內存利用率高,不會浪費內存 大小沒有固定,拓展很靈活。(每一個數據存儲了下一個數據的地址,增刪效率高)
鏈表的缺點:不能隨機查找,必須從第一個開始遍歷,查找效率低
4,數組和鏈表的代碼實現
說了這么多,讓我們用代碼來寫一個數組和鏈表。
數組:
1,先寫一個實體類DynamicArray;
主要包括屬性有數組容量,結點數據和數組長度;
1package com.java.model; 2 3public class DynamicArray { 4 //動態數組最大容量 5 public final static int capacity = 100; 6 7 //順序表的結點數據 8 public int[] data; 9 //順序表的長度,用來標識數組中的元素個數 10 public int size; 11 12 //構造函數 13 public DynamicArray(int[] data, int size) { 14 this.data = data; 15 this.size = size; 16 } 17}
2,再寫數組方法類DynamicArrayDao;
主要包括數組的各種操作方法,插入、查找等;
1package com.java.dao; 2 3import com.java.model.DynamicArray; 4import static com.java.model.DynamicArray.capacity; 5 6public class DynamicArrayDao { 7 8 //初始化數組 9 public DynamicArray Init_Array(){ 10 //數組數據域初始化 11 int[] data1=new int[capacity]; 12 13 //DynamicArray初始化 14 DynamicArray myArray=new DynamicArray(data1,0); 15 16 //數組賦值 17 for(int i=0;i<capacity;i++){ 18 myArray.data[i]=0; 19 } 20 return myArray; 21 } 22 23 //插入指定值 24 public void PushBack_Array(DynamicArray array,int value){ 25 if(array==null){ 26 return; 27 } 28 //如果線性表容量小於或等於數組容量 29 if(array.size==capacity){ 30 return; 31 } 32 //插入元素 33 array.data[array.size]=value; 34 array.size++; 35 } 36 37 //根據位置刪除 38 public void RemoveByPos_Array(DynamicArray array,int pos){ 39 if (array == null){ 40 return; 41 } 42 //判斷位置是否有效 43 if(pos < 0 || pos >= array.size){ 44 return; 45 } 46 //刪除元素 47 for (int i = pos; i < array.size -1; i ++){ 48 array.data[i] = array.data[i + 1]; 49 } 50 array.size--; 51 } 52 53 //查找元素,返回該值第一次出現時對應的下標位置 54 public int Find_Array(DynamicArray array,int value){ 55 if(array==null){ 56 return -1; 57 } 58 //找到該值第一次出現的位置,-1表示沒有找到; 59 int pos=-1; 60 for(int i=0;i<array.size;i++){ 61 if(array.data[i]==value){ 62 pos=i; 63 break; 64 } 65 } 66 return pos; 67 } 68 69 //根據位置查找到某個元素 70 public int At_Array(DynamicArray array,int pos){ 71 if(array==null){ 72 return -1; 73 } 74 return array.data[pos]; 75 } 76 77 //根據值刪除 78 public void RemoveByValue_Array(DynamicArray array,int value){ 79 if(array==null){ 80 return; 81 } 82 //首先找到該值對應的數組下標 83 int pos=Find_Array(array,value); 84 //調用根據位置刪除的方法 85 RemoveByPos_Array(array,pos); 86 } 87 88 //打印 89 public void Print_Array(DynamicArray array){ 90 if(array==null){ 91 return; 92 } 93 for(int i=0;i<array.size;i++){ 94 System.out.print(array.data[i]+","); 95 } 96 } 97 98 //清空數組 99 public void Clear_Array(DynamicArray array){ 100 if(array==null){ 101 return; 102 } 103 for(int i=0;i<array.size;i++){ 104 array.data[i]=0; 105 } 106 array.size=0; 107 } 108 109 //獲得動態數組當前元素個數 110 public int Size_Array(DynamicArray array){ 111 if(array==null){ 112 return -1; 113 } 114 return array.size; 115 } 116}
3,主函數Main;
包括測試各種函數等;
1package com.java.main; 2 3import com.java.dao.DynamicArrayDao; 4import com.java.model.DynamicArray; 5import static com.java.model.DynamicArray.capacity; 6 7public class DynamicArrayMain { 8 public static void main(String[] args) { 9 DynamicArrayDao dynamicArrayDao=new DynamicArrayDao(); 10 //初始化動態數組 11 DynamicArray myArray=dynamicArrayDao.Init_Array(); 12 System.out.println("初始化動態數組:"); 13 //獲取容量 14 System.out.println("數組容量:"+capacity); 15 System.out.println("數組實際大小:"+dynamicArrayDao.Size_Array(myArray)); 16 //插入元素 17 for(int i=0;i<10;i++){ 18 dynamicArrayDao.PushBack_Array(myArray,i); 19 } 20 System.out.println(); 21 22 System.out.println("插入元素之后:"); 23 //獲取容量 24 System.out.println("數組容量:"+capacity); 25 System.out.println("數組實際大小:"+dynamicArrayDao.Size_Array(myArray)); 26 System.out.println(); 27 28 //打印插入元素 29 System.out.println("打印插入的元素:"); 30 dynamicArrayDao.Print_Array(myArray); 31 System.out.println(); 32 33 //根據元素位置刪除元素 34 dynamicArrayDao.RemoveByPos_Array(myArray,2); 35 //根據元素值刪除元素 36 dynamicArrayDao.RemoveByValue_Array(myArray,7); 37 System.out.println(); 38 39 //打印刪除后的數組 40 System.out.println("打印刪除后的元素:"); 41 dynamicArrayDao.Print_Array(myArray); 42 System.out.println(); 43 44 //查找元素為5的位置 45 System.out.println(); 46 System.out.print("元素5的位置為: "); 47 int pos=dynamicArrayDao.Find_Array(myArray,5); 48 System.out.println(pos); 49 50 //查找位置為7的元素值 51 System.out.println(); 52 System.out.print("位置為7的元素為: "); 53 int value=dynamicArrayDao.At_Array(myArray,7); 54 System.out.println(value); 55 56 //獲取容量 57 System.out.println(); 58 System.out.println("此時的數組容量:"+capacity); 59 System.out.println("此時的數組實際大小:"+dynamicArrayDao.Size_Array(myArray)); 60 System.out.println(); 61 } 62}
運行效果:
鏈表:
1,先建立鏈表結點以及整個鏈表的實體類;
這里有兩個實體類:
LinkNode是結點,包括結點的數據域和指針域;
LinkList是整個鏈表,包括頭結點以及鏈表元素個數;
1package com.java.model; 2 3public class LinkNode { 4 //鏈表結點的數據域 5 public Object data; 6 //鏈表結點的指針域 7 public LinkNode next; 8 9 public LinkNode() { 10 super(); 11 // TODO Auto-generated constructor stub 12 } 13 14 //構造方法 15 public LinkNode(Object data, LinkNode next) { 16 super(); 17 this.data = data; 18 this.next = next; 19 } 20 21}
1package com.java.model; 2 3public class LinkList { 4 //鏈表的頭結點 5 public LinkNode head; 6 //鏈表的元素個數 7 public int size; 8 9 public LinkList() { 10 super(); 11 // TODO Auto-generated constructor stub 12 } 13 14 ///構造方法 15 public LinkList(LinkNode head, int size) { 16 super(); 17 this.head = head; 18 this.size = size; 19 } 20 21}
2,再寫鏈表方法類LinkListDao;
1package com.java.dao; 2 3import com.java.model.LinkList; 4import com.java.model.LinkNode; 5 6public class LinkListDao { 7 //初始化鏈表 8 public LinkList Init_LinkList(){ 9 //設置頭結點的指針域和數據域 10 LinkNode node=new LinkNode(0,null); 11 LinkList list=new LinkList(node,0); 12 return list; 13 } 14 //指定位置插入 15 public void Insert_LinkList(LinkList list, int pos, Object data){ 16 //判斷list是否有效 17 if(list==null){ 18 return; 19 } 20 //判斷data是否有效 21 if (data==null){ 22 return; 23 } 24 //判斷位置pos是否有效 25 if (pos<0 || pos>list.size){ 26 //在鏈表的尾部插入 27 pos = list.size; 28 } 29 30 //第一步,創建新的結點,也就是待插入的結點 31 LinkNode newNode=new LinkNode(data,null); 32 //第二步,找到待插入結點前面一個結點pCurrent,並使其等於list的頭結點 33 LinkNode pCurrent=list.head; 34 for(int i = 0 ; i < pos ; i++){ 35 pCurrent=pCurrent.next; 36 } 37 //第三步,新結點入鏈表,進行插入操作 38 newNode.next=pCurrent.next; 39 pCurrent.next=newNode; 40 //第四步,鏈表的size要加1 41 list.size++; 42 43 } 44 //刪除指定位置的值 45 public void RemoveByPos_LinkList(LinkList list, int pos){ 46 if(list==null){ 47 return; 48 } 49 if(pos<0||pos>=list.size){ 50 return; 51 } 52 //第一步,找到待刪除結點的前面一個結點pCurrent 53 LinkNode pCurrent=list.head; 54 for (int i = 0; i < pos; i++) { 55 pCurrent=pCurrent.next; 56 } 57 //第二步,進行刪除操作 58 pCurrent.next=pCurrent.next.next; 59 //第三步,鏈表的size要減1 60 list.size--; 61 } 62 //獲得鏈表的長度 63 public int Size_LinkList(LinkList list){ 64 return list.size; 65 } 66 //查找指定元素的位置 67 public void Find_LinkList(LinkList list, Object data){ 68 //注意這里要從頭結點的下一個結點開始,因為頭結點不存放數據信息 69 LinkNode pCurrent=list.head.next; 70 for (int i = 0; i < list.size; i++) { 71 if(pCurrent.data==data){ 72 System.out.print(i+","); 73 } 74 pCurrent=pCurrent.next; 75 } 76 } 77 //返回第一個結點元素的值 78 public Object Front_LinkList(LinkList list){ 79 return list.head.next.data; 80 } 81 //打印鏈表結點 82 public void Print_LinkList(LinkList list){ 83 if(list==null){ 84 return; 85 } 86 LinkNode pCurrent=list.head.next; 87 for (int i = 0; i < list.size; i++) { 88 System.out.print(pCurrent.data+","); 89 pCurrent=pCurrent.next; 90 } 91 } 92 93}
3,主函數Main;
測試各種方法類;
1package com.java.main; 2 3import com.java.dao.LinkListDao; 4import com.java.model.LinkList; 5 6public class LinkListMain { 7 public static void main(String[] args) { 8 LinkListDao linkListDao=new LinkListDao(); 9 //創建鏈表 10 LinkList list=linkListDao.Init_LinkList(); 11 12 //數據插入鏈表 13 linkListDao.Insert_LinkList(list, 0, "A"); 14 linkListDao.Insert_LinkList(list, 1, "B"); 15 linkListDao.Insert_LinkList(list, 2, "C"); 16 linkListDao.Insert_LinkList(list, 3, "D"); 17 linkListDao.Insert_LinkList(list, 4, "D"); 18 19 //打印鏈表 20 System.out.println("插入數據之后的鏈表為:"); 21 linkListDao.Print_LinkList(list); 22 System.out.println(); 23 24 //刪除指定位置的值 25 linkListDao.RemoveByPos_LinkList(list, 2); 26 27 //打印鏈表 28 System.out.println("刪除元素C之后的鏈表為:"); 29 linkListDao.Print_LinkList(list); 30 System.out.println(); 31 32 //獲得鏈表長度 33 System.out.println("鏈表長度為:"); 34 System.out.println(linkListDao.Size_LinkList(list)); 35 36 //查找值為3的位置 37 System.out.println("值為D的位置為:"); 38 linkListDao.Find_LinkList(list, "D"); 39 System.out.println(); 40 41 //返回第一個結點元素的值 42 System.out.println("第一個結點元素為:"); 43 System.out.println(linkListDao.Front_LinkList(list)); 44 } 45}
運行結果:
文中代碼格式是仿照MVC模式寫的,建議大家也這樣寫,比較整齊我感覺。
這次就分享到這里了,后續還有一系列的數據結構的文章哦,請大家期待!
右下角點個再看吧!蟹蟹哦~