Java實現的基礎數據結構


Java實現的基礎數據結構

0,常用的基礎數據結構

圖1 基礎數據結構&相關特性

圖2 Java自帶的類集框架&繼承關系圖

1,數組【Array】

  特點:長度固定、查找方便【直接使用index查找即可】、增加、刪除麻煩。

圖3 數組【查找直接使用index指針即可直接查詢】

圖4 數組添加【需要重新創建新數組對象並產生垃圾空間】

圖5 數組刪除【需要重新創建新數組並且產生垃圾空間】

  ①創建實例化數組對象

 1 public class Demo1_Array {
 2     public static void main(String[] args) {
 3         String [] array=new String[5];//需要初始化長度
 4         array[0]="hello";
 5         array[1]="world";
 6         array[4]="Mufasa";
 7 //        array[5]="right or not";//ArrayIndexOutOfBoundsException
 8         for(String str:array){
 9             System.out.print(str+"、");//hello、world、null、null、Mufasa、
10         }
11     }
12 }

  ②對實例化數組進行擴容【利用Java反射機制】

 1 public class Demo1_Array2 {
 2     public static void main(String[] args) {
 3         String [] array={"hello","world",null,null,"Mufasa"};//實例化&賦值
 4         array = (String[])resizeArray(array,10);
 5         for(String str:array){
 6             System.out.print(str+"、");//hello、world、null、null、Mufasa、
 7         }
 8     }
 9 
10     private static Object resizeArray(Object oldArray, int newSize) {//數組擴容!!!真麻煩,還利用反射機制來實現
11         int oldSize = java.lang.reflect.Array.getLength(oldArray);//獲取舊數組長度,向上轉型!!!
12 //        int oldSize =oldArray.length;//無法在此使用,因為array內容的是不定類型
13         Class elementType = oldArray.getClass().getComponentType();//獲取對象類別
14         Object newArray = java.lang.reflect.Array.newInstance(elementType,newSize);//利用Java的反射機制實例化新數組
15         int preserveLength = Math.min(oldSize, newSize);//判斷是否需要copy數據
16         if (preserveLength > 0)
17             System.arraycopy(oldArray, 0, newArray, 0, preserveLength);
18         return newArray;//oldArray切斷索引成為垃圾由Runtime.getRuntime().gc();回收處理
19     }
20 }

   ③數組刪除與增添,本質上是創建新的數值並且copy數值【需要私有反射實例化新數組,這里需要進一步優化】

 1 public class Demo1_Array4 {
 2     public static void main(String[] args) {
 3         String [] array=new String[5];//需要初始化長度
 4         array[0]="hello";
 5         array[1]="world";
 6         array[4]="Mufasa";
 7         array=drop(array,3);
 8         for(String str:array){
 9             System.out.print(str+"、");//hello、world、null、null、Mufasa、
10         }
11 
12     }
13     public static String[] drop(Object[] oldArray,int index){//刪除指定位置上的元素
14         int size= java.lang.reflect.Array.getLength(oldArray);
15         if(index<0 || index>size) {
16             throw new RuntimeException("刪除索引范圍有誤");
17         }else {
18             Class elementType = oldArray.getClass().getComponentType();//獲取對象類別
19             Object newArray = java.lang.reflect.Array.newInstance(elementType,size-1);
20             String[] newStringArray=(String[])newArray;
21             int counter=0;
22             for(int i=0;i<oldArray.length;i++){
23                 if(i!=index){
24                     newStringArray[counter]= (String) oldArray[i];
25                     counter++;
26                 }else {
27                     continue;
28                 }
29             }
30             return newStringArray;
31         }
32     }
33 }

  ④數組添加元素,本質也是創建新數組長度+1拷貝,index后移、賦值

 1 public class Demo1_Array5 {
 2     public static void main(String[] args) {
 3         String [] array=new String[5];//需要初始化長度
 4         array[0]="hello";
 5         array[1]="world";
 6         array[4]="Mufasa";
 7         array=add(array,3,"添加字符串");
 8         for(String str:array){
 9             System.out.print(str+"、");//hello、world、null、null、Mufasa、
10         }
11 
12     }
13     public static String[] add(Object[] oldArray,int index,String str){//刪除指定位置上的元素
14         int size= java.lang.reflect.Array.getLength(oldArray);
15         if(index<0 || index>size) {
16             throw new RuntimeException("添加索引范圍有誤");
17         }else {
18             Class elementType = oldArray.getClass().getComponentType();//獲取對象類別
19             Object newArray = java.lang.reflect.Array.newInstance(elementType,size+1);
20             String[] newStringArray=(String[])newArray;
21             int counter=0;
22             for(int i=0;i<oldArray.length;i++){
23                 if(i!=index){
24                     newStringArray[counter]= (String) oldArray[i];
25                     counter++;
26                 }else {
27                     newStringArray[counter]= (String) oldArray[i];
28                     counter++;
29                     newStringArray[counter]=str;
30                     counter++;
31                 }
32             }
33             return newStringArray;
34         }
35     }
36 }

  備注:當然也可以直接使用Java自帶的類集框架中的ArrayList、Vector

 1 import java.util.ArrayList;
 2 import java.util.List;
 3 
 4 public class Demo1_Array6 {
 5     public static void main(String[] args) {
 6         List<String> array=new ArrayList<>();//需要初始化長度
 7         array.add("hello");
 8         array.add("world");
 9 //        array.set(2,"Mufasa");
10         array.add("擴容!");
11         System.out.println(array.size());
12         for(String str:array){
13             System.out.print(str+"、");//hello、world、null、null、Mufasa、
14         }
15     }
16 }

  Vector中方法使用sychronized修飾符,線程安全【與ArrayList的區別】;

2,鏈表【Linked List】

   使用Node節點進行設計,功能:基本的setter、getter、add、getSize、remove等功能。

圖6 鏈表

圖7 鏈表增加【不用重新創建對象,不產生垃圾空間】

圖8 鏈表刪除【①斷開②重新建立鏈接】

  1 class Node{
  2     private String str=null;
  3     private Node nextNode=null;
  4     public Node(String str){
  5         this.str=str;
  6     }
  7     public void add(Node nextNode){//先遍歷到最后一個再添加
  8         Node indexNode=this.nextNode;
  9         while(true){
 10             if(indexNode.hasNext()==false){
 11                 break;
 12             }
 13             indexNode=indexNode.getNextNode();
 14         }
 15         indexNode.setNextNode(nextNode);
 16     }
 17     /*
 18     public void add(Node nextNode,int index){//方法重載,指定位點上添加元素
 19         if(index==0){
 20             String str_mid=this.str;
 21             this.str=nextNode.getStr();
 22             this.nextNode.setStr(str_mid);
 23             this.nextNode.setNextNode();
 24         }
 25         Node indexNode=this.nextNode;
 26         int size=1;
 27         while(true){
 28             if(indexNode.hasNext()==false || size==index){
 29                 break;
 30             }
 31             size++;//放在后面0開始
 32             indexNode=indexNode.getNextNode();
 33             System.out.println("size:"+size+",元素:"+indexNode.getStr());
 34         }
 35         if(size<index){
 36             throw new RuntimeException("添加元素索引超出范圍");
 37         }else {
 38             nextNode.setNextNode(indexNode.getNextNode());//先在新節點后加入
 39             indexNode.setNextNode(nextNode);//后在前面節點加入新節點
 40         }
 41     }*/
 42 
 43     public int getSize(){
 44         int size=0;
 45         Node indexNode=this.nextNode;
 46         while(true){
 47             size++;
 48             if(indexNode.hasNext()==false){
 49                 break;
 50             }
 51             indexNode=indexNode.getNextNode();
 52         }
 53         return size;
 54     }
 55     public void setNextNode(Node nextNode) {
 56         this.nextNode = nextNode;
 57     }
 58 
 59     public Node getNextNode() {
 60         return this.nextNode;
 61     }
 62 
 63     public String getStr() {
 64         return str;
 65     }
 66     public void setStr(String str){
 67         this.str=str;
 68     }
 69     public boolean hasNext(){
 70         if(nextNode!=null){
 71             return true;
 72         }else {
 73             return false;
 74         }
 75     }
 76 }
 77 
 78 public class Demo2_LinkedList {
 79     public static void main(String[] args) {
 80         String[] array={"begin","1","2","3","4","5"};
 81         Node rootNode=null;
 82         Node indexNode=null;
 83         boolean flag=true;
 84         for(String str:array){
 85             if(flag){
 86                 rootNode=new Node(str);
 87                 indexNode=rootNode;
 88                 flag=false;
 89             }else {
 90                 indexNode.setNextNode(new Node(str));
 91                 indexNode=indexNode.getNextNode();
 92             }
 93         }
 94         rootNode.add(new Node("添加元素"),2);
 95         indexNode=rootNode;
 96 //        System.out.println(rootNode.getSize());
 97         while(true){
 98             System.out.println(indexNode.getStr());
 99             if(indexNode.hasNext()==false){
100                 break;
101             }
102             indexNode=indexNode.getNextNode();
103         }
104     }
105 }

 

3,棧【Stack】

  先進后出的一種數據結構,解決方法:①雙向鏈表,略;②數組后續遍歷;

  使用Vector數組構建Stack

 1 import java.util.List;
 2 import java.util.Vector;
 3 
 4 class Stack_m<T>{//使用泛型
 5     private List<T> stack=new Vector<T>();
 6     public void push(T t){
 7         stack.add(t);
 8     }
 9     public T pop(){
10         int size=stack.size();
11         T mid;
12         mid=stack.get(size-1);
13         stack.remove(size-1);
14         return mid;
15     }
16 }
17 public class Demo3_Stack {
18     public static void main(String[] args) {
19         Stack_m stack_m=new Stack_m();
20         stack_m.push("hello");
21         stack_m.push("world");
22         stack_m.push("Mufasa");
23         stack_m.push("最后一個push");
24         for(int i=0;i<4;i++){
25             System.out.println(stack_m.pop());
26         }
27     }
28 }

4,隊列【Queue】

  通用:先進先出,一端輸入另一端輸出;特殊:優先隊列。

  使用Vector實現通用隊列

 1 import java.util.List;
 2 import java.util.Vector;
 3 
 4 class Queue_m<T>{
 5     private List<T> stack=new Vector<T>();
 6     public void add(T t){
 7         stack.add(t);
 8     }
 9     public T offer(){
10         int size=stack.size();
11         T mid;
12         mid=stack.get(0);
13         stack.remove(0);
14         return mid;
15     }
16 }
17 public class Demo4_Queue {
18     public static void main(String[] args) {
19         Queue_m queue_m=new Queue_m();
20         queue_m.add("hello");
21         queue_m.add("world");
22         queue_m.add("Mufasa");
23         queue_m.add("最后一個push");
24         for(int i=0;i<4;i++){
25             System.out.println(queue_m.offer());
26         }
27     }
28 }

  使用Vector實現優先隊列PriorityQueue【待:泛型這個還沒處理好】

 1 import java.util.List;
 2 import java.util.Vector;
 3 
 4 class Queue_m1<T>{
 5     private List<T> queue=new Vector<T>();
 6     public void add(T t){
 7         int index=0;
 8         for(T temp:queue){
 9         }
10             queue.add(t);
11     }
12     public T offer(){
13         int size=queue.size();
14         T mid;
15         mid=queue.get(0);
16         queue.remove(0);
17         return mid;
18     }
19 //    private boolean compareTo(T t1,T t2){//需要覆寫compareTo
20 //        if()
21 //        return
22 //    }
23 }
24 
25 public class Demo4_PriorityQueue {
26     public static void main(String[] args) {
27         Queue_m queue_m=new Queue_m();
28         queue_m.add("hello");
29         queue_m.add("world");
30         queue_m.add("Mufasa");
31         queue_m.add("最后一個push");
32         for(int i=0;i<4;i++){
33             System.out.println(queue_m.offer());
34         }
35     }
36 }

 

5,圖【Graph】

  圖數據結構有兩種表現形式:①鄰接矩陣形式;②鄰接表形式;

 1 import java.util.LinkedList;
 2 import java.util.Vector;
 3 
 4 class Graph_m1{//有兩種類型,類型1:鄰接矩陣形式
 5     private Vector<Vector<Integer>> graph=new Vector<Vector<Integer>>();//疊加Vector,【行】為Vector,【列】為元素
 6     private Vector<Integer> midVector;
 7     public Graph_m1(){}
 8     public void add(Vector<Integer> midVector){//方法重載
 9         this.graph.add(midVector);
10     }
11     public void add(int index1,Vector<Integer> midVector){//方法重載
12         this.graph.add(index1,midVector);
13     }
14     public void add(int index1, int t){//方法重載
15         midVector=graph.get(index1);
16         midVector.add(t);
17         graph.set(index1,midVector);
18     }
19     public void add(int index1, int index2, int t){//方法重載
20         midVector=graph.get(index1);
21         midVector.add(index2,t);
22         graph.set(index1,midVector);
23     }
24     public void set(int index1, int index2, int t){
25         midVector=graph.get(index1);
26         midVector.set(index2,t);
27         graph.set(index1,midVector);
28     }
29     public int get(int index1,int index2){
30         midVector=graph.get(index1);
31         return midVector.get(index2);
32     }
33     public void getAll(){
34         for(Vector<Integer> temp:graph){
35             for(Integer temp1:temp){
36                 System.out.print(temp1+",");
37             }
38             System.out.println("");
39         }
40     }
41 }
42 class Graph_m2<T>{//形式2:鄰接表形式
43     private LinkedList<LinkedList<T>> graph =new LinkedList<LinkedList<T>>();
44     private LinkedList<T> midLinkedList;
45     //set,get,getAll方法
46     public void add(LinkedList<T> midLinkedList){
47         this.graph.add(midLinkedList);
48     }
49     public void add(int index1,LinkedList<T> midLinkedList){
50         this.graph.add(index1,midLinkedList);
51     }
52 
53     public void getAll(){
54         for(LinkedList<T> temp:this.graph){
55             for(T temp1:temp){
56                 System.out.print(temp1+",");
57             }
58             System.out.println();
59         }
60     }
61 }
62 public class Demo5_Graph {
63     public static void main(String[] args) {
64         Graph_m2 graph=new Graph_m2();
65         LinkedList<Integer> linkedList;
66         for(int i=0;i<3;i++){
67             linkedList=new LinkedList<Integer>();
68             for(int j=0;j<5;j++){
69                 linkedList.add(j+i);
70             }
71             graph.add(linkedList);
72         }
73         graph.getAll();
74     }
75 }

 

 

6,樹【Tree】

   可以簡單理解為一種特殊的不包含圈的單向圖【發散型】。具體有:普通樹、二叉樹【最常用】、堆【heap】、哈夫曼樹。

  這里暫時只考慮二叉樹的結構。 

圖xx 二叉樹

通用二叉樹實現代碼【使用Node】

 1 class BinTree{
 2     private String str;
 3     private BinTree leftTree;
 4     private BinTree rightTree;
 5     public BinTree(String str){
 6         this.str=str;
 7     }
 8 
 9     public void setStr(String str) {
10         this.str = str;
11     }
12 
13     public void setLeftTree(BinTree leftTree) {
14         this.leftTree = leftTree;
15     }
16 
17     public void setRightTree(BinTree rightTree) {
18         this.rightTree = rightTree;
19     }
20 
21     public String getStr() {
22         return str;
23     }
24 
25     public BinTree getLeftTree() {
26         return leftTree;
27     }
28 
29     public BinTree getRightTree() {
30         return rightTree;
31     }
32 
33 }
34 
35 public class Demo6_Tree {
36     public static void main(String[] args) {
37         BinTree rootTree=new BinTree("a");
38         rootTree.setLeftTree(new BinTree("b"));
39         rootTree.setRightTree(new BinTree("c"));
40 
41         BinTree midTree=null;
42         midTree=rootTree.getLeftTree();
43         midTree.setLeftTree(new BinTree("d"));
44         midTree.setRightTree(new BinTree("e"));
45 
46         midTree=rootTree.getRightTree();
47         midTree.setLeftTree(new BinTree("f"));
48         midTree.setRightTree(new BinTree("g"));
49     }
50 }

 

 

7,堆【Heap】

 

借用Java類集中的ArrayList實現Heap

 1 import java.util.ArrayList;
 2 
 3 class Heap_m{
 4     private ArrayList<Integer> arryList=new ArrayList<Integer>();
 5     private boolean type;//true表示最大堆,false表示最小堆
 6     private Integer mid_i;//只是負責數據交換
 7     public Heap_m(boolean type){
 8         this.type=type;
 9     }
10 
11     public void add(int i){
12         arryList.add(i);
13         shiftUp(this.arryList.size()-1);
14     }
15     public int deletRoot(){//刪除根節點並返回其值
16         int mid_root=this.arryList.get(0);
17         this.mid_i=this.arryList.get(this.arryList.size()-1);
18         this.arryList.remove(this.arryList.size()-1);
19         this.arryList.set(0,this.mid_i);
20         shiftDown(0);
21         return mid_root;
22     }
23     public int delet(int index){//刪除指定index節點,並返回其值
24         if(index<0 || index>this.arryList.size()-1){
25             throw new IndexOutOfBoundsException("刪除節點index范圍有誤");
26         }
27         int mid_value=this.arryList.get(index);
28         this.mid_i=this.arryList.get(this.arryList.size()-1);
29         this.arryList.remove(this.arryList.size()-1);
30         this.arryList.set(index,this.mid_i);
31         shiftDown(index);
32         return mid_value;
33     }
34 
35     private void shiftUp(int index){//添加數據的時候進行操作
36         if(type){//最大堆
37             if((index-1)/2!=-1){
38                 if(this.arryList.get((index - 1) / 2) <this.arryList.get(index)){
39                     mid_i=this.arryList.get((index - 1) / 2);
40                     this.arryList.set((index - 1) / 2,this.arryList.get(index));
41                     this.arryList.set(index,mid_i);
42                     shiftUp((index - 1) / 2);//遞歸調用
43                 }
44             }
45         }else {//最小堆
46             if((index-1)/2!=-1){
47                 if(this.arryList.get((index - 1) / 2) >this.arryList.get(index)){
48                     mid_i=this.arryList.get((index - 1) / 2);
49                     this.arryList.set((index - 1) / 2,this.arryList.get(index));
50                     this.arryList.set(index,mid_i);
51                     shiftUp((index - 1) / 2);//遞歸調用
52                 }
53             }
54         }
55     }
56 
57     private void shiftDown(int index){//刪除數據的時候進行操作
58         if(type){//最大堆
59             if(index*2+1 < this.arryList.size()){
60                 if(this.arryList.get(2*index+1) >this.arryList.get(index)){
61                     mid_i=this.arryList.get(2*index+1);
62                     this.arryList.set(2*index+1,this.arryList.get(index));
63                     this.arryList.set(index,mid_i);
64                     shiftDown(2*index+1);//遞歸調用
65                 }
66             }
67         }else {//最小堆
68             if(index*2+1 < this.arryList.size()){
69                 if(this.arryList.get(2*index+1) <this.arryList.get(index)){
70                     mid_i=this.arryList.get(2*index+1);
71                     this.arryList.set(2*index+1,this.arryList.get(index));
72                     this.arryList.set(index,mid_i);
73                     shiftDown(2*index+1);//遞歸調用
74                 }
75             }
76         }
77     }
78 
79     public ArrayList<Integer> getHeap_m() {
80         return this.arryList;
81     }
82 }
83 public class Demo7_Heap {
84     public static void main(String[] args) {
85 //        Heap_m heap_m=new Heap_m(true);
86         Heap_m heap_m=new Heap_m(false);
87         heap_m.add(5);
88         heap_m.add(10);
89         heap_m.add(1);
90         heap_m.add(7);
91         heap_m.add(2);
92         System.out.println(heap_m.getHeap_m());
93         System.out.println(heap_m.deletRoot());
94         System.out.println(heap_m.getHeap_m());
95         heap_m.delet(-1);
96     }
97 }

 

8,散列表【Hash】

  特點:僅支持插入、查找、刪除

  

 

拉鏈型HashTable
 1 class HashTable_linked{//拉鏈型hashtable
 2     private Node[] values;
 3     private int j;
 4     public HashTable_linked(){//默認16長度,2的冥次方
 5         this.values=new Node[16];
 6     }
 7     public HashTable_linked(int length){//手動設置數據槽容量
 8         this.values=new Node[length];
 9     }
10     public void insert(int key,String value){
11         this.j=hashCode(key);
12         if(this.values[j]==null){//為空就添加root節點
13             this.values[j]=new Node(value);
14         }else {
15             this.values[j].add(new Node(value));
16         }
17     }
18     public Object search(int key){//通過key搜索某個元素
19         this.j=hashCode(key);
20         if(this.values[this.j]!=null){
21             return this.values[this.j];
22         }else{
23             return null;
24         }
25     }
26     private int hashCode(int key){//除余法散列函數h(k)=k%m
27         return key%this.values.length;
28     }
29 }
30 
31 public class Demo8_HashTable {
32     public static void main(String[] args) {//拉鏈型HashTable
33         HashTable_linked hashTable=new HashTable_linked(10);
34         hashTable.insert(11,"你好");
35         hashTable.insert(39,"世界");
36         hashTable.insert(22,"權利的游戲");
37         hashTable.insert(211,"努力奮斗");
38         hashTable.insert(211,"努力奮斗+1");
39         Node node=(Node)hashTable.search(211);
40         System.out.println(node.getStr());
41         System.out.println(node.getNextNode().getStr());
42         System.out.println(node.getNextNode().getNextNode().getStr());
43     }
44 }

鏈表Node數據結構:

 1 class Node{
 2     private String str=null;
 3     private Node nextNode=null;
 4     public Node(String str){
 5         this.str=str;
 6     }
 7     public void add(Node nextNode){//先遍歷到最后一個再添加
 8         Node indexNode=this;//當前對象
 9         while(true){
10             if(indexNode.hasNext()==false){
11                 break;
12             }
13             indexNode=indexNode.getNextNode();
14         }
15         indexNode.setNextNode(nextNode);
16     }
17     /*
18     public void add(Node nextNode,int index){//方法重載,指定位點上添加元素
19         if(index==0){
20             String str_mid=this.str;
21             this.str=nextNode.getStr();
22             this.nextNode.setStr(str_mid);
23             this.nextNode.setNextNode();
24         }
25         Node indexNode=this.nextNode;
26         int size=1;
27         while(true){
28             if(indexNode.hasNext()==false || size==index){
29                 break;
30             }
31             size++;//放在后面0開始
32             indexNode=indexNode.getNextNode();
33             System.out.println("size:"+size+",元素:"+indexNode.getStr());
34         }
35         if(size<index){
36             throw new RuntimeException("添加元素索引超出范圍");
37         }else {
38             nextNode.setNextNode(indexNode.getNextNode());//先在新節點后加入
39             indexNode.setNextNode(nextNode);//后在前面節點加入新節點
40         }
41     }*/
42 
43     public int getSize(){
44         int size=0;
45         Node indexNode=this.nextNode;
46         while(true){
47             size++;
48             if(indexNode.hasNext()==false){
49                 break;
50             }
51             indexNode=indexNode.getNextNode();
52         }
53         return size;
54     }
55     public void setNextNode(Node nextNode) {
56         this.nextNode = nextNode;
57     }
58 
59     public Node getNextNode() {
60         return this.nextNode;
61     }
62 
63     public String getStr() {
64         return str;
65     }
66     public void setStr(String str){
67         this.str=str;
68     }
69     public boolean hasNext(){
70         if(nextNode!=null){
71             return true;
72         }else {
73             return false;
74         }
75     }
76 }

 


免責聲明!

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



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