Java自定义链表

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/HcJsJqJSSM/article/details/78500752

                                                                                                              Java自定义链表

一:写在前面

             我们知道在数据结构中,就学习了链表,链式存储结构的线性表也称之为链表,链表的基础知识就不在这里啰嗦啦,毕竟网上的资源太多了.jdk的实现ArrayList(顺序存储)和LikedList(链式存储)

             对于单链表的常见的操作:

                  1:节点的数据查找.

                  2:节点的插入

                  3:节点的删除

             创建新的节点的三种方法:

                    头插法(表头插入)

                    尾插法(表尾插入)

                   一般的插法(按照给定的索引顺序插入节点) 

              重要的有:概念了

                    头节点

                    尾节点

 二:分析实现单链表

    先分析我们需要的数据结构,采用非静态内部类来实现.

    下面是源代码,每一步都注释的比较清楚,一看就明白啦.

    

public class LinkList<T> {
//定义一个内部类Node,Node就表示链表的节点
private class Node{
//表示链表的数据域
private T data;
//表示链表的指针域
private Node next;
//定义一个空的构造器
public Node(){};
//初始化链表的各个属性
public Node(T data,Node next){
this.data=data;
this.next=next;
}
}
//保存链表的头结点
private Node header;
//保存链表的尾节点
private Node tail;
//保存链表中的节点的数目
private int size;
//创建一个空链表
public LinkList(){
//由于是空链表,头结点和尾节点都为空
header=null;
tail=null;
size=0;
}
//以指定的元素创建一个链表,这个链表就只有一个元素的
public LinkList(T element){
header=new Node(element,null);
//只有一个节点,头尾相同
tail=header;
size++;
}
//返回链表的长度
public int length(){
return size;
}
//根据索引index来获取指定位置的节点,索引从0开始
public Node getNodeByIndex(int index){
    if(index<0||index>size-1){
    throw new IndexOutOfBoundsException("链表索引越界啦!");
    }else{
    //单链表从header节点
    Node current=header;
    for(int i=0;i<size&&current!=null;i++,current=current.next){
    if(i==index){
    return current;
    }
    }
   
    }
    return null;

}
//获取索引为index处的元素
public T get(int index){
return getNodeByIndex(index).data;
}
//查找指定元素的索引
public int locate(T element){
//从头节点开始寻找
Node current=header;
for(int i=0;i<size&&current!=null;i++,current=current.next){
if(current.data.equals(element)){
return i;
}
}
return -1;
}
//向链表指定的位置插入一个元素
public void insert(T element,int index){
if(index<0||index>size){
throw new IndexOutOfBoundsException("链表的索引越界!");
}
//如果是空链表
if(header==null){
add(element);
}else{
//当index=0时,就在链表的头结点插入
if(index==0){
addAtHeader(element);
}else{
//获取插入节点的前一个节点
Node prev=getNodeByIndex(index-1);
//让prev的next指向新增的节点,让新节点的next引用原来prev的下一个节点-就是在要在当前插入的节点.
prev.next=new Node(element,prev.next);
size++;
} 
}
}
//采用尾插法为链表添加新节点
public void add(T element){
//如果该链表是空链表
if(header==null){
header=new Node(element,null);
//只有一个节点
tail=header;
}else{
//创建新的节点
Node newNode=new Node(element,null);
//让尾节点的next指向新的节点
tail.next=newNode;
//让新增的节点作为新的尾节点
tail=newNode;
}
size++;
}
//采用头插法为链表添加新的节点
public void addAtHeader(T element){
//创建新的节点,让新的节点的next指向原来的header
//让新增的节点作为新的header
header=new Node(element,header);
//如果是空链表
if(tail==null){
tail=header;
}
size++;
}
//删除链表中指定索引处的元素
public T delete(int index){
if(index<0 || index>size-1){
throw new IndexOutOfBoundsException("线性表索引越界!");
}
//要删除的元素对应的节点
Node del=null;
//如果被删除的是header节点
if(index==0){
del=header;
//让头结点的下一个节点作为头结点
header=header.next;
}else{
//获取删除点前的一个节点
Node prev=getNodeByIndex(index-1);
//获取将要被删除的节点
del=prev.next;
//让被删除节点的next指向被删除节点的下一个节点
prev.next=del.next;
//释放被删除节点的引用
del.next=null;
}
size--;
return del.data;
}
   //删除链表的最后一个元素
   public T remove(){
       return delete(size-1);
   }
   //返回链表的尾节点的数据
   public T elementLast(){
      if(empty()){
       return null;
      }else{
       return tail.data;
      }
   }
   //返回链表的第一个节点的数据
   public T elementFirst(){
      if(empty()){
       return null;
      }else{
       return header.data;
      }
   }
   //判断链表是否为空
   public boolean empty(){
   return size==0;
   }
   //清空链表
   public void clear(){
   header=null;
   tail=null;
   size=0;
   }
   //返回
   public String toString(){
   //如果链表是空的
   if(empty()){
   return "[]";
   }else{
   StringBuilder sbBuilder=new StringBuilder("[");
   for(Node current=header;current!=null;current=current.next){
   sbBuilder.append(current.data.toString()+",");
   
   }
   int len=sbBuilder.length();
   return sbBuilder.delete(len-1, len).append("]").toString();
   }
   
   }
   public static void main(String[] args) {
      LinkList<String> list=new LinkList<String>();
      list.insert("aaaa", 0);
      list.add("bbbb");
      list.add("cccc");
      list.add("dddd");
      //list.remove();
      //list.clear();
      //list.delete(2);
      System.out.println(list.elementLast());
      System.out.println(list.elementFirst());
      System.out.println(list.empty());
      System.out.println(list.length());
      System.out.println(list);
}
}  

    运行结果如下:

           

    至于循环链表就是无头无尾.首尾相顾,从一端开始就可以回到起点的.tail.next=header;

          如果说,单链表是100米或200米跑道.那木循环链表就是400米跑道嘛.大概就是这个意思.

            

                       

阅读更多
换一批

没有更多推荐了,返回首页