线性表接口如下
/** * 尾节点的好处 可以更快的找到尾部节点 缺点就是增加了代码的复杂度 需要在插入和删除时候对尾节点进行维护 */}
package IntefaceList; public interface IList<T> { /** * 构造一个空的线性表 进行初始化 */ void InitList(); /** * 销毁线性表 */ IList DestroyList(); /** * 将线性表重置为空表 */ IList ClearList(); /** * 判断线性表是否为空 */ Boolean ListEmpty(); /** * 返回线性表中元素的个数 */ Integer ListLength(); /** * 获取线性表中第i个元素 */ T GetElem(Integer i); /** * 根据元素获取它的位序,如果有多个符合,则返回第一个,如果没有则返回0 */ Integer LocateElem(T e); /** * 获取该元素的上一个元素 */ T PriorElem(T e); /** *获取该元素的下一个元素 */ T NextElem(T e); /** * 在指定位置插入元素 */ IList ListInsert(Integer i, T e); /** *删除指定位置的元素 */ IList ListDelete(Integer i); /** * 遍历所有的元素 */ void ListTraverse(); /** * 合并两个线性表 合并不重复的元素 */ IList Union(IList list); /** * 按照递增顺序合并两个线性表 */ IList MergeList(IList list); /** * 在尾部新增元素 */ void add(T e); }
节点对象
//节点对象 public class LNode<T> { //数据 private T data; //下一个节点 private LNode<T> next; public T getData() { return data; } public void setData(T data) { this.data = data; } public LNode<T> getNext() { return next; } public void setNext(LNode<T> next) { this.next = next; } }
实现类 package Impl; import IntefaceList.IList; //todo 链表型线性表 public class LinkedList<T> implements IList { //头节点 private LNode<T> tnode; private Integer length = 0; //当前节点 private LNode<T> cnode; //尾巴节点 public LNode<T> getTnode() { return tnode; } private LNode<T> taillNode; @Override public void InitList() { tnode = new LNode<>(); //初始化头节点 taillNode = tnode; } @Override public IList DestroyList() { tnode.setNext(null); length = 0; //这里应该整个list对象为null 但java没有析构函数 taillNode = tnode; return this; } @Override public IList ClearList() { cnode = tnode.getNext(); while (cnode.getNext() != null) { cnode = cnode.getNext(); cnode.setData(null); length--; } taillNode = tnode; return this; } @Override public Boolean ListEmpty() { if (length != 0) { return Boolean.FALSE; } else { return Boolean.TRUE; } } @Override public Integer ListLength() { return this.length; } @Override public Object GetElem(Integer i) { cnode = tnode.getNext(); while (i - 1 > 0) { cnode = cnode.getNext(); i--; } return cnode.getData(); } @Override public Integer LocateElem(Object e) { cnode = tnode.getNext(); int i = 1; while (cnode != null && !e.equals(cnode.getData())) { i++; cnode = cnode.getNext(); } if (cnode == null) { return -1; } return i; } @Override public Object PriorElem(Object e) { cnode = tnode.getNext(); LNode<T> pnode = null; while (!e.equals(cnode.getData())) { pnode = cnode; //上一个节点 cnode = cnode.getNext(); } return pnode.getData(); } @Override public Object NextElem(Object e) { cnode = tnode.getNext(); while (!e.equals(cnode.getData())) { cnode = cnode.getNext(); } return cnode.getNext().getData(); } @Override public IList ListInsert(Integer i, Object e) { if (i > length) { //这个可能有问题 当在没有元素的时候 需要插入元素的时候 return null; } cnode = tnode.getNext(); LNode<T> newNode = new LNode<>(); newNode.setData((T) e); /** * 在最后一位插入 */ if (i.equals(this.length)) { newNode.setNext(null); newNode.setData(taillNode.getData()); taillNode.setData((T) e); taillNode.setNext(newNode); taillNode = newNode; return this; } if (i == 1) { newNode.setNext(cnode); tnode.setNext(newNode); return this; } while (i > 2) { cnode = cnode.getNext(); i--; } newNode.setNext(cnode.getNext()); cnode.setNext(newNode); length++; return this; } //todo 修改后的完美删除 @Override public IList ListDelete(Integer i) { cnode=tnode.getNext(); if (cnode==null){ return null; } int j=2; if (i==1){ tnode.setNext(cnode.getNext()); length--; return this; } while (cnode.getNext()!=null){ if (i==j){ cnode.setNext(cnode.getNext().getNext()); length--; return this; } j++; cnode=cnode.getNext(); } if (i==j){ cnode.setNext(null); length--; taillNode=cnode; } return null; } @Override public IList ListDelete(Integer i) { cnode = tnode.getNext(); /** * 如果删的是尾节点 */ if (i.equals(this.length)) { for (i = 1; i < this.length; i++) { cnode = cnode.getNext(); } taillNode = cnode; cnode.setNext(null); this.length--; return this; } while (i - 1 > 0) { cnode = cnode.getNext(); i--; } cnode.setNext(cnode.getNext().getNext()); length--; return this; } @Override public void ListTraverse() { cnode = tnode.getNext(); while (cnode.getNext() != null) { if (cnode.getData() != null) { System.out.print(cnode.getData() + ","); } cnode = cnode.getNext(); } System.out.print(cnode.getData() + ","); System.out.println(); } /** * 合并两个线性表中不重复的元素 * * @param list * @return */ @Override public IList Union(IList list) { for (int i = 1; i <= list.ListLength(); i++) { if ((this.LocateElem(list.GetElem(i))) == -1) { LNode<T> newNode = new LNode<>(); taillNode.setNext(newNode); newNode.setData((T) list.GetElem(i)); newNode.setNext(null); taillNode = newNode; this.length++; } } return this; } @Override public IList MergeList(IList list) { LinkedList<T> LB = (LinkedList<T>) list; //在已知道两个列表都是非递减序列的情况下合并 //要求合并之后还是非递减序列 //两个链表归并 要想不和数组型线性表一样借助第三个表实现 就得用到指针 知道节点的位置 LNode<T> pb = LB.getTnode().getNext(); LNode<T> pa = this.getTnode().getNext(); cnode = tnode; //当前节点 this.length = this.length + list.ListLength(); while (pa != null && pb != null) { if ((Integer) pa.getData() <= (Integer) pb.getData()) { cnode.setNext(pa); cnode = pa; pa = pa.getNext(); } else { cnode.setNext(pb); cnode = pb; pb = pb.getNext(); } } if (pa == null) { cnode.setNext(pb); } else { cnode.setNext(pa); } return list; } @Override public void add(Object e) { cnode = tnode.getNext(); LNode<T> newNode = new LNode<>(); newNode.setNext(null); newNode.setData((T) e); if (cnode != null) { while (cnode.getNext() != null) { cnode = cnode.getNext(); } cnode.setNext(newNode); } else { tnode.setNext(newNode); } taillNode = newNode; this.length++; } /** * 链表的逆置 就是每插入一个 都是在尾部往前插入 */ public void Reversal() { cnode = tnode.getNext(); if (cnode.getNext()==null){ return; } //第一个节点 LNode<T> firstNode =new LNode<>(); firstNode.setNext(null); firstNode.setData(cnode.getData()); tnode.setNext(firstNode); cnode = cnode.getNext(); while (cnode!= null) { //因为最后一个节点的next是null LNode<T> newNode =new LNode<>(); newNode.setData(cnode.getData()); newNode.setNext(tnode.getNext()); tnode.setNext(newNode); cnode = cnode.getNext(); } }
测试类
package test; import Impl.LinkedList; public class LinkedTest { public static void main(String[] args) { LinkedList<Integer> list=new LinkedList<>(); list.InitList(); // System.out.println(list.ListLength()); // list.ListInsert(1,9); // list.ListInsert(2,2); // list.ListInsert(3,6); // list.ListInsert(4,5); // list.ListInsert(5,9); list.add(3); list.add(5); list.add(88); list.add(111); // System.out.println(list.ListLength()); // // // list.ListTraverse(); System.out.println(list.GetElem(3)); System.out.println(list.LocateElem(88)); // System.out.println(list.PriorElem(99)); // System.out.println(list.NextElem(9)); // list.ListDelete(1); // list.ListTraverse(); // SequenceList<Integer> list2=new SequenceList<>(); // list2.InitList(); // list2.add(2); // list2.add(6); // list2.add(8); // list2.add(9); // list2.add(11); // list2.add(15); // list2.add(2000); // //list.Union(list2); // list.MergeList(list2); list.ListTraverse(); list.ListInsert(1,99); list.ListTraverse(); System.out.println(list.PriorElem(88)); System.out.println(list.NextElem(88)); } }
测试结果输出