第30 章 : 链表的定义与使用
134 链表实现简介
链表本质是一个动态的对象数组,它可以实现若干个对象的存储
链表利用引用的逻辑关系来实现类似于数组的数据处理操作
实现链表,需要一个公共结构-节点:
1、保存数据
2、连接下一个结构
Node<E> -E data -next
还需要一个管理Node节点的类
客户端:数据的增删改查 链表LinkImpl:处理Node细节 -> ILink<T> Node:存储数据
private class Node<T>{ private T data; // 数据 private Node<T> nextNode; // 下一节点 public Node(T data){ this.data = data ; } public void setNextNode(Node<T> nextNode){ this.nextNode = nextNode ; } public Node<T> getNextNode(){ return this.nextNode ; } public T getData(){ return this.data; } }
简单的单向链表实现
135 数据增加
public void add(E e);
136 获取数据集合个数
public int size();
137 空集合判断
public boolean isEmpty();
138 返回集合数据
public Object[] toArray();
139 根据索引取得数据
public E get(int index);
数组获取数据的时间复杂度为1
链表获取数据的时间复杂度为n
140 修改链表指定索引数据
public void set(int index, E data);
141 判断链表数据是否存在
public boolean contains(E data);
142 删除链表数据
public void remove(E data);
两种情况
删除根节点数据
删除非根节点数据
引用修改
143 清空链表
public void clean();
只用设置头节点为空即可
完整代码
// 定义链表的接口 interface ILink<E>{ public void add(E e); // 添加元素 public int size(); // 获取元素个数 public boolean isEmpty(); // 判断是否为空 public Object[] toArray(); //转为对象数组 public E get(int index); // 根据索引取得数据 public void set(int index, E data); //修改数据 public boolean contains(E data); // 判断数据是否存在 public boolean remove(E data); // 链表数据 public void clean(); // 清空链表 } // 实现链表 class LinkImpl<T> implements ILink<T>{ private Node<T> rootNode; // 记录头指针 private int count ; // 计数统计 private Object[] dataList; // 数据列表 private int foot; //角标 // 链表节点,内部类,便于外部类直接访问其私有属性 private class Node<T>{ private T data; // 数据 private Node<T> nextNode; // 下一节点 public Node(T data){ this.data = data ; } public void addNode(Node<T> node){ if(!this.hasNextNode()){ this.nextNode = node; } else{ this.nextNode.addNode(node); } } public boolean hasNextNode(){ return this.nextNode != null; } public void toArrayNode(){ LinkImpl.this.dataList[LinkImpl.this.foot++] = this.data; if(this.hasNextNode()){ this.nextNode.toArrayNode(); } } public Node<T> getNode(int index){ if(LinkImpl.this.foot++ == index){ return this ; }else{ return this.nextNode.getNode(index); } } public boolean containsNode(T data){ // 比较对象 不能是null if(this.data.equals(data)){ return true; } else { // 有后续节点继续 if(this.hasNextNode()){ return this.nextNode.containsNode(data); } else { // 没有找到数据 return false; } } } public boolean removeNode(Node<T> preNode, T data){ if(this.data.equals(data)){ preNode.nextNode = this.nextNode; return true; } else { // 有后续节点,继续移除操作 if(this.hasNextNode()){ return this.nextNode.removeNode(this, data); } else{ return false; } } } } public void add(T data){ // 不接受null 类型的值 if(!isValidData(data)){ return; } Node<T> newNode = new Node<T>(data); // 添加第一个元素的时候,头节点为null if (this.count == 0){ this.rootNode = newNode; } else { this.rootNode.addNode(newNode); } this.count++; } public int size(){ return this.count; } public boolean isEmpty(){ return this.count == 0; } public Object[] toArray(){ if(this.isEmpty()){ return null; } // 角标清零,创建空数组 this.foot = 0; this.dataList = new Object[this.count]; // 递归获取节点数据 this.rootNode.toArrayNode(); return this.dataList; } // 检查索引是否在有效范围内 private boolean isValidIndex(int index){ if(index < 0 || index >= count){ return false; } else{ return true; } } // 检查是否为有效数据 private boolean isValidData(T data){ if(data == null){ return false; } else{ return true; } } public T get(int index){ if(!this.isValidIndex(index) || this.isEmpty()){ return null ; } // 重置下标 this.foot = 0; return this.rootNode.getNode(index).data; } public void set(int index, T data){ if(!this.isValidIndex(index) || this.isEmpty() ){ return ; } // 重置下标 this.foot = 0; this.rootNode.getNode(index).data = data; } public boolean contains(T data){ if(!isValidData(data) || this.isEmpty()){ return false; } return this.rootNode.containsNode(data); } public boolean remove(T data){ if(!isValidData(data) || this.isEmpty()){ return false; } boolean removeResult = false; // 移除头节点 if(this.rootNode.data.equals(data)){ this.rootNode = this.rootNode.nextNode; removeResult = true; } else{ removeResult = this.rootNode.nextNode.removeNode(this.rootNode, data); } if(removeResult == true){ this.count --; } return removeResult; } public void clean(){ this.rootNode = null; this.count = 0; } public void printLink(){ Object[] list = this.toArray(); if (list == null){ System.out.println("null"); return; } for(int i=0; i < this.count; i++){ if(i == 0){ System.out.print("[ "); } else { System.out.print("-> "); } System.out.print(list[i]); if (i == count - 1){ System.out.print(" ]"); } } System.out.println(); } } class Demo{ public static void main(String[] args) { LinkImpl<Integer> link = new LinkImpl<Integer>(); System.out.println("添加前:" + link.size() + " " + link.isEmpty()); // 添加前:0 true link.add(2); link.add(3); link.add(4); link.add(5); System.out.println("添加后:" + link.size() + " " + link.isEmpty()); // 添加后:4 false link.printLink(); // [ 2-> 3-> 4-> 5 ] System.out.println(link.get(2)); // 4 link.set(2, 6); System.out.println(link.get(2)); // 6 System.out.println(link.contains(10)); // false System.out.println(link.contains(5)); // true link.printLink(); // [ 2-> 3-> 6-> 5 ] link.remove(2); System.out.println(link.contains(2)); link.printLink(); // [ 3-> 6-> 5 ] link.clean(); link.printLink(); // null } }
144 综合实战:宠物商店
要求
宠物上架,下架,查询宠物信息
设计
宠物接口
-猫
-狗
宠物链表接口
-宠物链表
宠物商店
-宠物列表
根据接口标准定义信息
145 综合实战:超市购物车
类与标准有关,降低类与类之间耦合
146 Eclipse简介
Eclipse 中文意思:日蚀
开发工具 + 操作系统 + 中间件 + 数据库
Eclipse EE + Linux + Tomcat + MySQL
https://www.eclipse.org/downloads/
147 使用JDT开发Java程序
项目目录
src *.java bin *.class
UTF-8编码
快捷方式:
自动导包
代码格式化
代码纠正提示
代码提示
复制当前行
单行注释
代码自动生成
148 代码调试
断点break point
单步跳入 进入代码
单步跳过 直接到结果
单步返回 进入之后直接返回
恢复执行 取消断点,程序正常执行
149 junit测试工具
白盒测试
黑盒测试
用例测试 junit
testCase 一个测试
testSuite 一组测试