数据结构01-线性表
说明:由于该数据结构是由java并且是原生实现,所以与C有一些出入,不过原理是相同的
1线性表的定义
一个线性表是由n个元素构成的有限序列(n>=0)。n=0时,线性表称为空表;当n>0时,线性表表示为(a1,a2,a3...an)a1称为线性表的第一个元素,an成为线性表的最后一个元素。除了第一个元素没有前驱结点和最后一个元素没有后继结点之外,其他节点都有唯一的前驱结点和后继结点。
2 实现原理
线性表是用数组实现的,包含一个数组和一个表示当前线性表大小的size :
class List<T>{ T[] sorte; int length; }
3 线性表的基本操作
1.init 初始化 生成一个空的线性表
2.clear 清空,删除线性表中全部元素,逻辑上清空线性表
3.destory 销毁线性表,不再使用该线性表(注意删除与清空的区别)
4.empty 判断当前线性表是否为空
5.length 获取线性表当前的长度
6.insert 插入一个元素
7.erase 删除第i个元素
8.remove 删除全部值为data的元素
9.add 添加一个元素到末尾
4 代码实现
4.1 线性表代码实现
1 2 3 import java.util.ArrayList; 4 import java.util.Arrays; 5 import java.util.Objects; 6 7 /** 8 * @Author: xiaobai 9 * @Date: 2019/4/30 22:03 10 * @email: 11 * @address: 12 * @desc: 模拟线性表操作 13 * @Version 1.0 14 */ 15 @SuppressWarnings("ALL") 16 public final class List<T> { 17 /** 18 * 用于存储值的数组 是线性表的核心(使用时根据泛型强转即可) 19 */ 20 private Object[] store; 21 22 /** 23 * 当前线性表的长度 24 */ 25 private int length; 26 27 /** 28 * 在第index个位置添加元素 索引从0开始 29 * @param index 添加位置 30 * @param data 被添加的元素 31 * @return 插入结果 32 */ 33 public boolean insert(int index,T data){ 34 //先判断是否在线性表之内 35 if(index>this.length || 0 > index){ 36 return false; 37 } 38 //如果存储控件不够则需要进行扩容操作 39 if(this.length+1>store.length){ 40 dilatation(); 41 } 42 //将要插入的数据之后的每一位都向后移动 43 for(int j = this.length+1;j>=index;j--){ 44 store[j] = store[j-1]; 45 } 46 //插入数据 47 store[index-1] = data; 48 //添加数据,长度加一 49 this.length++; 50 51 return true; 52 } 53 54 /** 55 * 删除线性表中第i个元素 56 * @param i 被删除元素的位置 57 * @return 删除的元素 删除失败返回null 58 */ 59 public T erase(int i){ 60 //如果索引不合法 返回null 61 if(i>this.length || 0>i){ 62 return null; 63 } 64 //先将被删除的元素取出 65 T curr = (T)this.store[i]; 66 //从被删除元素位置开始 依次向前移动一个位置 67 for(int j = i;j<length-1;j++){ 68 this.store[j] = this.store[j+1]; 69 } 70 //删除数据 长度减一 71 this.length--; 72 return curr; 73 } 74 75 /** 76 * 删除与data相等的元素 77 * @param data 比较相等的元素 78 * @return 删除的个数 79 */ 80 public int remove(T data){ 81 //被删除元素的个数 82 int count = 0; 83 for(int i=0;i<=this.length;i++){ 84 //如果相等 说明应该删除 85 if(compare(data,(T)this.store[i])){ 86 //删除一个元素 87 T del = erase(i); 88 if(null != del){ 89 //如果删除成功 则删除元素个数加一 90 count ++; 91 } 92 } 93 } 94 return count; 95 } 96 97 /** 98 * 向顺序表末尾添加一个数据 99 * @param data 被添加的数据 100 * @return 添加结果 101 */ 102 public boolean add(T data){ 103 //如果长度不够 则扩容 104 if(this.length+1>this.store.length){ 105 dilatation(); 106 } 107 this.store[this.length++] = data; 108 return true; 109 } 110 111 /** 112 * 相当于init方法,这里使用构造方法进行初始化 113 */ 114 public List(){ 115 this(16); 116 } 117 118 /** 119 * 相当于init方法,这里使用构造方法进行初始化 120 * @param defalut 初始化大小,如果不指定 默认16 121 */ 122 public List(int defalut){ 123 this.store = new Object[defalut]; 124 this.length = 0; 125 } 126 127 /** 128 * 清空线性表 逻辑清空 让长度等于0 即可 129 */ 130 public void clear(){ 131 this.length = 0; 132 } 133 134 /** 135 * 销毁线性表 使该线性表不可用 136 */ 137 public void destroy(){ 138 //这是不安全的 会导致空指针异常 139 this.store = null; 140 this.length = 0; 141 } 142 143 /** 144 *判断线性表是否为空 145 * 为空返回true 不为空返回false 146 */ 147 public boolean empty(){ 148 return this.length==0; 149 } 150 151 /** 152 * 获取线性表的长度 153 */ 154 public int length(){ 155 return this.length; 156 } 157 158 /** 159 * 扩容操作 160 */ 161 private void dilatation(){ 162 //开辟一个原数组1.5倍长度的新数组 163 Object[] newStore = new Object[(int)(store.length*1.5)]; 164 //将原来的值拷贝过来 165 System.arraycopy(store,0,newStore,0,store.length); 166 //使用新的数组,原数组由于没有引用会被GC线程回收 167 store = newStore; 168 } 169 170 /** 171 * 比较方法,用于判断两个对象是否相等 172 * 一般要求使用者重写这个方法或者重写所存储类型的equals方法 173 * @param t1 被比较对象1 174 * @param t2 被比较对象2 175 * @return 比较结果 176 */ 177 public boolean compare(T t1,T t2){ 178 //若有引用为空 认为不相等 179 if(null == t1 || null == t2){ 180 return false; 181 } 182 //基本类型值相等 引用类型地址相等认为相等 183 if(t1 == t2){ 184 return true; 185 } 186 //若地址不想等或者引用不相等 则调用存储对象的equals方法比较 187 return t1.equals(t2); 188 } 189 190 191 @Override 192 public String toString() { 193 StringBuilder sb = new StringBuilder().append("hashcode = "+this.hashCode()+" ").append("["); 194 for(int i=0;i<this.length;i++){ 195 sb.append(this.store[i]+" "); 196 } 197 sb.append("]"); 198 return sb.toString(); 199 } 200 }
4.2测试代码及结果
1 /** 2 * @Author: xiaobai 3 * @Date: 2019/4/30 22:53 4 * @email: 5 * @address: 6 * @Version 1.0 7 */ 8 public class TestMyList { 9 public static void main(String[] args) { 10 System.out.println("初始化线性表"); 11 List<Integer> testList = new List<>(); 12 System.out.println("当前线性表长度 "+testList.length()); 13 System.out.println("线性表是否为空 "+testList.empty()); 14 for(int i=1;i<=20;i++){ 15 testList.add(i); 16 } 17 System.out.println("添加20个元素后线性表长度 "+testList.length()); 18 System.out.println("线性表内容 "+testList); 19 20 System.out.println("在第五个位置上插入100 "+testList.insert(5,100)); 21 System.out.println("插入后的线性表 "+testList); 22 23 System.out.println("删除第0个位置的数据 "+testList.erase(0)); 24 System.out.println("删除后的线性表 "+testList); 25 26 //再插入两个8 加上之前的一共有三个8 27 testList.add(8);testList.add(8); 28 System.out.println("删除所有值为8的元素 共删除: "+testList.remove(8)); 29 System.out.println("删除8后的线性表 "+testList); 30 31 testList.clear(); 32 System.out.println("清空线性表后线性表长度:"+testList.length()); 33 System.out.println("清空后的线性表 "+testList); 34 35 testList.destroy(); 36 37 } 38 }
运行结果: