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 }
原文地址:https://www.cnblogs.com/Mufasa/p/11213982.html