数据结构学习----线性表(Java版的实现)
2014-10-15 16:22 雪夜&流星 阅读(3784) 评论(0) 编辑 收藏 举报线性表接口LList:
package com.clarck.datastructure.linear; /** * 线性表接口LList,描述线性表抽象数据类型,泛型参数T表示数据元素的数据类型 * * @author clarck * */ public interface LList<T> { /** * 判断线性表是否空 * @return */ boolean isEmpty(); /** * 返回线性表长度 * @return */ int length(); /** * 返回第i(i≥0)个元素 * @param i * @return */ T get(int i); /** * 设置第i个元素值为x * @param i * @param x */ void set(int i, T x); /** * 插入x作为第i个元素 * @param i * @param x */ void insert(int i, T x); /** * 在线性表最后插入x元素 * @param x */ void append(T x); /** * 删除第i个元素并返回被删除对象 * @param i * @return */ T remove(int i); /** * 删除线性表所有元素 */ void removeAll(); /** * 查找,返回首次出现的关键字为key元素 * @param key * @return */ T search(T key); }
顺序表(线性表的顺序存储结构)类,实现线性表接口,T是泛型参数,指定任意类
package com.clarck.datastructure.linear; /** * 顺序表(线性表的顺序存储结构)类,实现线性表接口,T是泛型参数,指定任意类 * * @author clarck * * @param <T> */ public class SeqList<T> implements LList<T> { /** * 对象数组,保护成员 */ protected Object[] element; /** * 顺序表长度,记载元素个数 */ protected int len; /** * 默认构造方法,创建默认容量的空表 */ public SeqList() { this(64); } /** * 构造方法,创建容量为size的空表 * * @param size */ public SeqList(int size) { this.element = new Object[size]; this.len = 0; } /** * 判断顺序表是否空,若空返回true,O(1) */ @Override public boolean isEmpty() { return this.len == 0; } /** * 返回顺序表长度,O(1) */ @Override public int length() { return this.len; } /** * 返回第i(≥0)个元素。若i<0或大于表长则返回null,O(1) */ @SuppressWarnings("unchecked") @Override public T get(int i) { if (i >= 0 && i < this.len) { return (T) this.element[i]; } return null; } /** * 设置第i(≥0)个元素值为x。若i<0或大于表长则抛出序号越界异常;若x==null,不操作 */ @Override public void set(int i, T x) { if (x == null) return; if (i >= 0 && i < this.len) { this.element[i] = x; } else { throw new IndexOutOfBoundsException(i + ""); // 抛出序号越界异常 } } /** * 顺序表的插入操作 插入第i(≥0)个元素值为x。若x==null,不插入。 若i<0,插入x作为第0个元素;若i大于表长,插入x作为最后一个元素 */ @Override public void insert(int i, T x) { if (x == null) return; // 若数组满,则扩充顺序表容量 if (this.len == element.length) { // temp也引用elements数组 Object[] temp = this.element; // 重新申请一个容量更大的数组 this.element = new Object[temp.length * 2]; // 复制数组元素,O(n) for (int j = 0; j < temp.length; j++) { this.element[j] = temp[j]; } } // 下标容错 if (i < 0) i = 0; if (i > this.len) i = this.len; // 元素后移,平均移动len/2 for (int j = this.len - 1; j >= i; j--) { this.element[j + 1] = this.element[j]; } this.element[i] = x; this.len++; } /** * 在顺序表最后插入x元素 */ @Override public void append(T x) { insert(this.len, x); } /** * 顺序表的删除操作 删除第i(≥0)个元素,返回被删除对象。若i<0或i大于表长,不删除,返回null。 */ @SuppressWarnings("unchecked") @Override public T remove(int i) { if (this.len == 0 || i < 0 || i >= this.len) { return null; } T old = (T) this.element[i]; // 元素前移,平均移动len/2 for (int j = i; j < this.len - 1; j++) { this.element[j] = this.element[j + 1]; } this.element[this.len - 1] = null; this.len--; return old; } /** * 删除线性表所有元素 */ @Override public void removeAll() { this.len = 0; } /** * 查找,返回首次出现的关键字为key元素 */ @SuppressWarnings("unchecked") @Override public T search(T key) { int find = this.indexOf(key); return find == -1 ? null : (T) this.element[find]; } /** * 顺序表比较相等 比较两个顺序表是否相等 ,覆盖Object类的equals(obj)方法,O(n) */ @SuppressWarnings("unchecked") @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj instanceof SeqList) { SeqList<T> list = (SeqList<T>) obj; // 比较实际长度的元素,而非数组容量 for (int i = 0; i < this.length(); i++) { if (!this.get(i).equals(list.get(i))) { return false; } } return true; } return false; } /** * 顺序查找关键字为key元素,返回首次出现的元素,若查找不成功返回-1 * * @param key * 可以只包含关键字数据项,由T类的equals()方法提供比较对象相等的依据 * @return */ public int indexOf(T key) { if (key != null) { for (int i = 0; i < this.len; i++) { // 对象采用equals()方法比较是否相等 if (this.element.equals(key)) { return i; } } } return -1; } // 返回顺序表所有元素的描述字符串,形式为“(,)”,覆盖Object类的toString()方法 public String toString() { String str = "("; if (this.len > 0) str += this.element[0].toString(); for (int i = 1; i < this.len; i++) str += ", " + this.element[i].toString(); return str + ") "; // 空表返回() } }
线性表的顺序表示和实现,测试类:
package com.clarck.datastructure.linear; /** * 线性表的顺序表示和实现 * * @author clarck * */ public class SeqList_test { public static void main(String args[]) { //空表 SeqList<String> lista = new SeqList<String>(4); System.out.println("lista is empty: "+lista.toString()); //扩容 for (int i = 5; i >= 0; i--) { lista.insert(i, new String((char)('A' + i) + "")); } System.out.println("lista insert finished: "+lista.toString()); lista.set(3, new String((char)(lista.get(3).charAt(0) + 32) + "")); System.out.println("lista set 3 : "+lista.toString()); lista.remove(0); System.out.println("lista remove 0 position: "+lista.toString()); lista.remove(3); System.out.println("lista remove 3 position: "+lista.toString()); } }
输出结果:
lista is empty: () lista insert finished: (A, F, B, E, C, D) lista set 3 : (A, F, B, e, C, D) lista remove 0 position: (F, B, e, C, D) lista remove 3 position: (F, B, e, D)
源码:https://github.com/clarck/DataStructure/tree/master/Linear/src/com/clarck/datastructure/linear
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本