双向链表——Java实现

 
 

双向链表

链表是是一种重要的数据结构,有单链表和双向链表之分;本文我将重点阐述不带头结点的双向链表:

                                

不带头结点的带链表

我将对双链表的增加和删除元素操作进行如下解析

   1.增加元素(采用尾插法)

(1)链表为空

     新建结点,将头结点first和尾节点last都指向新建结点,尾节点的next指向空。

 

空链表增加元素

(2)链表非空

     先定义一个临时的结点temp保存当前的尾节点,将尾节点last指向新建结点,并将lastprev指向temptempnext指向last.

                                       

非空链表增加元素

2.删除指定下标的元素

我将分以下三种情况进行讨论

(1)要删除元素为头结点

 node保存当前头结点first,并将头结点first指向first.next且将现在的first.prev置为空,将node.nextdata分别置为空。

                                       

删除头结点

(2)要删除元素为尾节点

      用节点node保存当前的尾节点,将last指向当前尾节点的前一个节点last.prev,并将现last.next置为空,将以前的lastnode节点的prevdata置空。

  

删除尾结点

(3)要删除元素为中间节点

      用节点node保存要删除的节点,并将要删除节点的前一个节点的next指向要删除节点的下一个节点;要删除节点的下一个节点的prev指向要删除节点的还是那个一个节点;即node.prev. next = node.nextnode.next.prev = node.prev。并将要删除节点的prevnextdata置为null.

                              

删除中间结点

package Struct;

interface Link{
	void add(Object obj);
	boolean remove(int index);
	boolean contain(Object obj);
	int indexOf(Object obj);
	boolean set(int index,Object obj);
	Object get(int index);
	int length();
	void clear();
	Object[] toArray();
	void printArray(Object[] obj);
	void printLink();
}
class Factory{
	private Factory(){}
	public static Link getLinkInstance(){
		return new LinkImpl();
	}
}
class LinkImpl implements Link{
	private Node first;
	private Node last;
	private int size;
	private class Node{
		private Node prev;
		private Node next;
		private Object data;
		public Node(Object data){
			this.data = data;
		}
	}
	public void add(Object obj) {
		//要插入元素为空
		if(obj == null){
			return;
		}
		Node node = new Node(obj);
		//空链表
		if(first == null){
			first = last = node;
			first.next = null;
			size++;
		}else{
		//非空链表(尾插)
			Node temp = this.last;
			temp.next = node;
			last = node;
			last.prev = temp;
			size++;
		}
	}
	//删除
	public boolean remove(int index) {
		//指定下标不合法
		if(index >= size){
			return false;
		}
		Node node = first;
		//要删除的节点为头结点
		if(index == 0){
			first = node.next;
			first.prev = null;
			node.prev = node.next = null;
			node.data = null;
			size--;
			return true;
		}
		//要删除节点为尾节点
		if(index == size-1){
			Node node1 = last;
			last = node1.prev;
			last.next = null;
			node1.prev = node1.next = null;
			node1.data = null;
			size--;
			return true;
		} 
		//要删除节点为中间节点
			Node node3 = get(index);
			node3.prev.next = node3.next;
			node3.next.prev = node3.prev;
			node3.prev = node3.next = null;
			node3.data = null;
			size--;
			return true;
	}
	//查看元素是否包含在链表中
	public boolean contain(Object obj) {
		//空链表
		if(first == null&&first.next==null){
			return false;
		}
		for(Node node = first;node!=null;node=node.next){
			if(node.data==obj){
				return true;
			}
		}
		return false;
	}
	//求取元素obj的下标
	public int indexOf(Object obj) {
		Node node  = first;
		int signal = 0;
		//空链表
		if(first== null&& first.next == null){
			return -1;
		}else{
			for(node = first;node!=null;node=node.next){
				if(node.data == obj){
					return signal;
				}
				signal++;
			}
		}
		return signal;
	}
	//修改index处的值为obj
	public boolean set(int index, Object obj) {
		//指定位置不存在
		if(index<0||index >= size){
			return false;
		}
		//指定下标超过链表长度
		if(index >= size){
			return false;
		}
		Node node = first;
		//若链表头结点是要修改的元素
		if(node == get(index)){
			node.data = obj;
		}
		Object getObject = get(index);
		for(node = first;node !=null;node=node.next){
			if( getObject == node){
				node.data = obj;
			}
		}
		return true;
	}
	//取得index处的元素
	public Node get(int index) {
		if(first==null&&first.next==null){
			return null;
		}
		//要查找下标不在范围内
		if(index >= size){
			return null;
		}
		Node node = first;
		//要查找元素在中间元素的左侧
		if(index >=0 && index <= (index<<1)){
			for(int i = 0;i <= index - 1;i++){
				if(i == index){
					return node;
				}
				node =node.next;
			}
		}
		else if(index > (index<<1)){
        //要查找元素在中间元素的右侧
			for(int i = index; i < size-1;i++){
				if(i == index){
					return node;
				}
				node = node.next;
			}
		}
			return node;
	}
	//求链表长度
	public int length() {
		//空链表
		if(first == null){
			return 0;
		}
		return this.size;
	}
	//清空链表
	public void clear() {

		Node node = first;
		if(first == null && first.next == null){
			return;
		}
		for(node = first.next;node!=null;){
			Node temp = node;
			node.prev = node.next = null;
			node.data = null;
			node = node.next;
			size--;
		}
		first.next = null;
		first.data = null;
		size--;
	}
	//将链表转换成Object数组
	public Object[] toArray() {
		//空链表
		if(first == null && first.next == null){
			return null;
		}else{
			Object[] linkObject = new Object[this.size];//向上转型
			Node node = first;
			for(int i = 0;i<size;i++){	
				linkObject[i] = node.data;
				node = node.next;
				}
			return linkObject;
		}
	}
	//打印Object数组
	public void printArray(Object[] obj){
		for(int i = 0;i < obj.length;i++){
			System.out.print(obj[i]+" <-> ");
		}
	}
	//打印链表
	public void printLink() {
		Node node = first;
		for(node = first;node!=null;node=node.next){
			System.out.print(node.data+" <——> ");
		}
		System.out.println();
	}
	
}
public class DoubleLinkList {
	public static void main(String[] args) {
		Link link = Factory.getLinkInstance();
		System.out.println("\n"+"=================以下为add测试函数===================");
		link.add("我是开始位置");
		link.add("第一名");
		link.add("第二名");
		link.add("第三名");
		link.add("我是结束位置");
		System.out.println("\n"+"===============以下为printLink测试函数===============");
		link.printLink();
		System.out.println("\n"+"===============以下为indexOf测试函数================");
		System.out.println(link.indexOf("第二名"));
		System.out.println(link.indexOf("我是结束位置"));
		System.out.println("\n"+"===============以下为contain测试函数================");
		System.out.println(link.contain("我是结束位置"));
		System.out.println(link.contain("hahh"));
		System.out.println("\n"+"===============以下为get测试函数================");
		System.out.println(link.get(0));
		System.out.println(link.get(4));
		System.out.println(link.get(2));
		System.out.println(link.get(8));
		System.out.println("\n"+"===============以下为length测试函数================");
		System.out.println(link.length());
		System.out.println("\n"+"===============以下为set测试函数===================");
		System.out.println(link.set(0, "我是特等奖"));
		link.printLink();
		System.out.println("\n"+"===============以下为toArray测试函数===================");
		Object[] linkObj = link.toArray();
		System.out.println("\n"+"===============以下为printArray测试函数===================");
		link.printArray(linkObj);
		System.out.println("\n"+"===============以下为remove测试函数===================");
		//删除尾节点
		System.out.println(link.remove(4));
		link.printLink();
		//删除头结点
		System.out.println(link.remove(0));
		link.printLink();
		//删除中间节点
		System.out.println(link.remove(1));
		link.printLink();
		System.out.println(link.length());
		System.out.println("\n"+"===============以下为clear测试函数===================");
		link.clear();
		System.out.println(link.length());
	}
}
测试结果:


猜你喜欢

转载自blog.csdn.net/qq_40409115/article/details/79947487