淺談數組和鏈表


​寫在前面:

數組和鏈表是數據結構中最基礎的兩種結構,其他的都是由這兩者轉化而來;
因此,掌握這兩種結構至關重要!下面,時光就帶大家來學習一下數組和鏈表;

思維導圖:

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模式寫的,建議大家也這樣寫,比較整齊我感覺。
這次就分享到這里了,后續還有一系列的數據結構的文章哦,請大家期待!

                               右下角點個再看吧!蟹蟹哦~

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM