数据结构之双向链表(Java实现)

1.双向链表的概述与节点结构
数据结构之双向链表(Java实现)_第1张图片
2.双向链表的API设计
数据结构之双向链表(Java实现)_第2张图片
3.双向链表的时间复杂度分析:
数据结构之双向链表(Java实现)_第3张图片

4.源码实现:

package linkList;

import java.util.Iterator;

public class TwoWayLinkList<T> implements Iterable<T>{

	//首节点
	private Node head;
	//尾节点
	private Node last;
	//链表长度
	private int N;
	
	
	//节点类
	private class Node{
		//存储数据
		public T item;
		//指向上一个节点
		public Node pre;
		//指向下一个节点
		public Node next;
		//构造方法
		public Node(T item,Node pre, Node next){
			this.item=item;
			this.next=next;
			this.pre=pre;
		}
	}
	
	//构造方法:创建Twowaylinklist对象
	public TwoWayLinkList(){
		//初始化头节点,刚开始没有前驱也没有后继,只需要一个节点即可
		this.head=new Node(null,null,null);
		//初始化尾节点,刚开始是没有尾节点的
		this.last=null;
		//初始化元素个数
		this.N=0;
	}
	
	//清空链表
	public void clear(){
		this.head.next=null;
		this.last.pre=null;
		this.N=0;
	}
	
	//判断是否为空
	public boolean isEmpty(){
		return N==0;
	}
	
	//获取链表中元素的个数
	public int length(){
		return N;
	}
	
	//读取并返回链表中第i个元素的值
	public T get(int i){
		Node n=head;
		for(int index=0;index<i;index++){
			n=n.next;
		}
		return n.item;
	}
	
	//往线性表中添加一个元素
	public void insert(T t){
		//如果链表为空
		if(isEmpty()){
			//创建新节点
			Node newNode=new Node(t,head,null);
			//让新节点成为尾节点
			last=newNode;
			//让头节点指向尾节点
			head.next=last;
		}
		//如果链表不为空
		else{
			//创建新节点
			Node newNode=new Node(t, last, null);
			//让当前的尾节点指向新节点
			last.next=newNode;
			//让新节点成为尾节点
			last=newNode;
		}
		//元素个数+1
		N++;
	}
	
	//在线性表中第i个元素之前插入一个值为t的元素
	public void insert(int i,T t){
		//找到i位置的前一个节点
		Node pre=head;
		for(int index=0;index<i;index++){
			pre=pre.next;
		}
		//找到i位置的节点
		Node curr=pre.next;
		//创建新节点
		Node newNode=new Node(t,pre,curr);
		//让i-1位置的next变为新节点
		pre.next=newNode;
		//让i位置的pre变为新节点
		curr.pre=newNode;
		//元素个数+1
		N++;
	}
	
	//删除并返回链表中第i个元素的数据
	public T remove(int i){
		//找到i位置的前一个节点
		Node pre=head;
		for(int index=0;index<i;index++){
			pre=pre.next;
		}
		//找到i位置的节点
		Node curr=pre.next;
		//让i-1位置的节点的next变为i.next
		pre.next=curr.next;
		//让i+1位置的节点的pre变成i.pre
		curr.next.pre=curr.pre;
		//元素个数-1
		N--;
		return curr.item;
	}
	
	//返回线性表中首次出现指定元素的序号,若不存在则返回-1
	public int indexOf(T t){
		Node n=head;
		for(int i=0;n.next!=null;i++){
			n=n.next;
			if(n.item.equals(t)){
				return i+1;
			}
		}
		return -1;
	}
	
	//获取第一个元素
	public T getFirst(){
		//安全性验证
		if(isEmpty()){
		return null;
		}
		else{
			return head.next.item;
		}
	}
	
	//获取最后一个元素
	public T getLast(){
		//安全性验证
		if(isEmpty()){
		return null;
		}
		else{
			return last.item;
		}
	}
	
	//遍历
	public static void foreach(TwoWayLinkList<String> list){
		for(String str:list){
			System.out.print(str+"->");
		}
		System.out.println();
	}

	/*
	 * 实现Iterable接口返回一个Iterator对象从而实现遍历
	 * 但是Iterator也是一个接口所以不能直接返回,这时需要一个类来实现Iterator接口从而返回改实现类的对象即可
	 */
	@Override
	public Iterator<T> iterator() {
		// TODO Auto-generated method stub
		return new TIterator();
	}
	
	private class TIterator implements Iterator{
        private Node pre;
        public TIterator() {
		this.pre=head;
        	// TODO Auto-generated constructor stub
		}
		@Override
		public boolean hasNext() {
			// TODO Auto-generated method stub
			return pre.next!=null;
		}

		@Override
		public Object next() {
			// TODO Auto-generated method stub
			pre=pre.next;
			return pre.item;
		}	
	}
}

5.测试类实现:

package linkList;

public class TwoWayLinkListTest {
  public static void main(String[] args) {
	 TwoWayLinkList<String> list1=new TwoWayLinkList<String>();
	 //测试插入
	 list1.insert("蜘蛛侠");
	 list1.insert("蝙蝠侠");
	 list1.insert("钢铁侠");
	 list1.insert("美国队长");
	 list1.foreach(list1);
	 System.out.println("\n---------------------------------------------------");
	 //测试指定位置插入
	 list1.insert(2, "雷神");
	 list1.insert(3,"绿巨人");
	 list1.foreach(list1);
	 System.out.println("\n---------------------------------------------------");
	 //测试删除
	 list1.remove(1);
	 list1.foreach(list1);
	 System.out.println("\n---------------------------------------------------");
	 //测试获取
	 System.out.println(list1.get(3));
	 System.out.println("\n---------------------------------------------------");
	 //测试第一个元素和最后一个元素
	 System.out.println(list1.getFirst());
	 System.out.println(list1.getLast());
	 System.out.println("\n---------------------------------------------------");
	 //测试索引
	 System.out.println(list1.indexOf("钢铁侠"));
	 System.out.println("\n---------------------------------------------------");
	 //测试长度
	 System.out.println(list1.length());
	 //是否为空
	 System.out.println("是否为空:"+list1.isEmpty());
  }
 
}

你可能感兴趣的:(经典程序,数据结构,线性表,数据结构,链表,java)