链表开发案例
package com.start;
public class LinkDemo {
public static void main(String[] args) {
Link all = new Link(); //创建链表对象
all.add(new Book("Java开发", 89.56));
all.add(new Book("Oracle数据库开发", 99));
all.add(new Book("Androld开发", 56.2));
System.out.println("保存的节点有:"+all.size());
System.out.println(all.contains(new Book("Java实战经典", 78.8)));
all.contains(new Book("Android开发实战经典", 78.8));
// all.remove(new Book("Java开发",89.56));
all.remove(new Book("Oracle数据库开发", 99));
all.remove(new Book("Androld开发", 56.2));
Book[] books = all.toArray();
// for(int x = 0 ;x<books.length; x++) {
// System.out.println(books[x]);
// }
}
}
/**
* 定义一个类保存图书信息
* 保存图书测名称、图书的价格
* compare()方法判断对是否和Book对象相同
* @author Administrator
*
*/
class Book{
private String title ;
private double price;
public Book(String title, double price) {
super();
this.title = title;
this.price = price;
}
/**
* 进行对本类对象比较,首先判断是否为null,在判断地址是否相同
* 如果都相同再进行对象内容判断,由于compare()方法就收的是本类引用,所以直接访问私有属性
* @param book
* @return
*/
public boolean compare(Book book) {
if(book == null) {
return false ;
}
if(this == book) { // 直接判断内存地址
return true ;
}
if(this.title.equals(book.title) && this.price==book.price) {
return true;
}else {
return false;
}
}
//覆写toString()方法
public String getInfo() {
return "图书名称是:"+this.title+"图书价格:"+this.price;
}
}
/**
* 创建链表是实现类
* @author Administrator
*
*/
class Link{
/***
* 定义Node节点操作类
* @author Administrator
*
*/
/******************************内部类操作节点关系****************************************/
private class Node{
private Book data ;//保存数据
private Node next ;//保存下一个节点
public Node() {
super();
}
public Node(Book data) {
this.data = data ;// 保存节点数据
}
/***
* 保存新的节点,所有的节都保存在最后一个节点之后
* 如果当前节点不是下一个将节点,那么继续寻找下一个节点,下一个节点还不是最后一个节点,在递归继续寻找。找到最后一个节点为止,找到最后一个节点之后把当前添加的节点保存在下一个(next)节点对象中
* @param newNode
*/
public void addNode(Node newNode) {
if(this.next == null) { //判断是当前节点是否为最后一个节点,如果next为null,则为最后一个节点
this.next = newNode; //因为next表示下一个节点,如果next为null的,说明这里没有下一个节点了,就发newNode新的节点保存在next下一个节点的位置
}else {
this.next.addNode(newNode);//证明还有下一个节点,在继续判断。这里当前对象点next下一个节点时,已经是判断下一个节点的数据了
}
}
/**
* 数据检索操作(指定数据查询是否存在)
*
* @param data 需要查询的数据
* @return
*/
public boolean containsNode(Book data) {
if(this.data.compare(data)) { //判断当前对象data和传过来的data对象是否相同 compare()方法专门为Book对象比较而设计
return true;
}else {
if(this.next.data.compare(data)) { //如果不存用户传输过来的data不在当前对象中,那么在去下一个对象中寻找
return true ;
}else {
return false;
}
}
}
/**
* 根据索引取出数据
* @return
*/
public Book getNode(int index ){
if(Link.this.foot == index) {
return this.data;//返回数据
}else {
return this.next.getNode(index); //递归,下一个节点在判断
}
}
/****
* 指定下标修改数据
* @param idnex
* @param data
*/
public void setNode(int index,Book data) {
if(Link.this.foot == index) { //根据指定的下标查询到对应节点
this.data = data ;//参数传过来的数据f覆盖原来节点上的数据
}else {
this.next.setNode(index, data);//如果没有,下一个节点继续
}
}
/***
* 节点删除操作,匹配每一个节点的数据,如果当节点数据符合则删除
* @param previous
* @param data
*/
public void removeNode(Node previous,Book data) {
if(data.compare(this.data)) { //参数传过来的节点与当前节点比较,
previous.next = this.next;//空出当前节点。如果data与当期节点相同了,那么把当前节点赋值给previous对象
}else {
this.next.removeNode(previous, data);//如果两个对象不相同,下一个节点继续
}
}
/**
* 把当前节点内容保存到数组中
*/
public void toArrayNode() {
Link.this.retArray[Link.this.foot] = this.data; //Link.this.foot为下标。把当前对象保存到数组中
}
}
/******************************内部类操作结束****************************************/
private Node root ;//保存节点定义
private int cunt = 0 ;//保存节点个数
private int foot ;//保存节点下标
private Book[] retArray;//返回数组
/***
* 向链表中添加数据,在添加数据时必须封装到Node类中,这样才能匹配节点数据
* @param data
*/
public void add(Book data) {
if(data == null) {
return ;
}
Node newNode = new Node(data); //需要保存的数据
if(this.root==null) { //判断当前节点是否为空节点
this.root = newNode; //把节点数据保存在根节点中
}else { //如果不是空节点,就交给Node去处理节点顺序
this.root.addNode(newNode);
}
this.cunt++;//节点的个数增加 +1
}
/**
* 取得节点中的个数
* @return
*/
public int size() {
return this.cunt;
}
/**
* 判断是否为空链表
* @return
*/
public boolean isEmpty() {
return this.cunt == 0 ;
}
/**
* 数据查询操作,判断指定数据是否存在,如果链表中没有数据则返回false
* @param data
* @return
*/
public boolean contains(Book data) {
if(data == null || this.root == null) { //root保存的是根节点,如果根节点为null,那么说名该链表中没有数据的。如果查询的参数data为null,链表中冶不会存在的
return false;
}
return this.root.containsNode(data);//Node内部类中去查询
}
/***
* 根据下标查询数据
* @param index
* @return
*/
public Book get(int index) {
if(index >this.cunt) { //判断查询的下标是否在链表保存节点个数的范围内
return null ;
}
this.foot =0;//表示存第一个开始查询
return root.getNode(index);//内部类处理
}
/***
* 根据下标修改数据
* @param index 修改数据的下标
* @param data 需要修改的内容
*/
public void set(int index,Book data) {
if(index > this.cunt) { //判断index是超过链表范围内
return;//结束方法调用
}
this.foot = 0 ;//存第一个开始查询
this.root.setNode(index, data);//交给内部类处理
}
/***
* 链表数据的删除操作,在删除前首先适应contains()判断链表中是否存在指定的数据
* 如果要是删除数据,首先判断根节点的数据是否需要删除
* 如果是,则将根节点的下一个节点作为新根节点
* 如果删除的数据不是根节点数据,则将删除操作交给Node内部类removeNode()方法去处理
* @param data
*/
public void remove(Book data) {
if(this.contains(data)) { //判断数据是否存在
//判断删除的数据是否为根节点数据,root是Node类的对象,removeNode()方法完成
if(data.equals(this.root.data)) { //这里的root保存的是节点中的定义,this.root.data为根节点 【删除的数据为根节点数据】
this.root = this.root.next;//空出当前节点 ,让下一个节点作为当前节点
}else {//删除的数据不是根节点数据
//此时根节点元素已经判断过了,从第二个元素开始判断,从第二个元素的上一个元素为根节点(因为根节点没有删除)
this.root.removeNode(this.root, data); //交给内部类处理
}
this.cunt -- ;//节点个数减 -1
}
}
/***
* 将链表中的数据转为数组输出
* @return 如果链表没有数据返回 null
*/
public Book[] toArray() {
if(this.root == null) { //判断链表是否为null
return null;
}
this.foot = 0 ;//索引从0开始
this.retArray= new Book[this.cunt]; //根据保存的数据开辟内存
this.root.toArrayNode(); //交给Node类处理赋值操作
return this.retArray;
}
/**
* 清空链表
*/
public void clear() {
this.root = null ;
this.cunt = 0;
}
}