Java双向链表实现

本文实现了java双链表的基本的增删改查功能。有不足之处,望不吝赐教。

 

双链表 注意要点

双链表实现时第一个节点的前驱为空,最后一个节点的后驱为空。

2  删除尾节点 不需要从头开始遍历 从结尾开始遍历 复杂度变为O(1)

3  删除节点的本质是取消其他节点对该节点的引用

4  无论是删除指定位置的节点还是删除指定数据的节点 本质上是删除current指向的节点

5  插入节点本质上是在current 以及 current之前的prior  之间插入节点

6 searchItem 方法的while内部的判断条件为 while(current.data!=data&&current.next!=null) 为的是保证下面的current.data不会抛出NullPoiterException 。搜索到最后一个位置时,current为最后节点,判断此前的节点的info是否等于data,等于data,则返回,不等,则不存在该元素。

7 这里pos与current同步,pos从1开始,删除节点就是删除current。 

 

package com.marthevin.linkedlist;


public class DoublyListTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		DoublyList doublyListTest = new DoublyList();
		
		doublyListTest.addFirstNode(32);
		doublyListTest.addFirstNode(23);
		doublyListTest.addFirstNode(56);
		doublyListTest.addFirstNode(212);
		doublyListTest.addFirstNode(6565);
		doublyListTest.addFirstNode(986);
		doublyListTest.addFirstNode(345);
		doublyListTest.addLastNode(3434);
//		System.out.println("链表原长度:"+doublyListTest.lenth());
//		doublyListTest.insertNodeByPos(2, 555);
//		doublyListTest.addFirstNode(555);
//		doublyListTest.deleteNodeByData(345);
//		doublyListTest.deleteNodeByPos(5);
//		System.out.println("链表现有长度:"+doublyListTest.lenth());

		doublyListTest.deleteNodeByData(3434);
		doublyListTest.displayForward();
		
	}

}
class DNode
{
	DNode next,back;
	int data;
	public DNode(int data)
	{
		this.data = data;
		this.next = null;
		this.back = null;
	}
}

class DoublyList
{
	DNode first,last;
	int count = 0;
	int pos = 1;
	
	public DoublyList()
	{
		this.first = null;
		this.last = null;
		this.count = 0;	
	}
	//确定链表是否为空
	public boolean isEmpty()
	{
		return this.count==0;
	}
	//确定链表的长度
	public int lenth()
	{
		return this.count;
	}
	//正向输出链表
	public void displayForward()
	{
		DNode current = first;
		if(first==null)
		{
			System.out.println("空链表!");
		}else{
			while(current!=null)
			{
				System.out.print(" "+current.data);
				current = current.next;
			}
		}
	}
	//反向输出链表
	public void displayBackward()
	{
		DNode current = last;
		if(first==null)
		{
			System.out.println("空链表!");
		}else{
			while(current!=null)
			{
				System.out.print(" "+current.data);
				current = current.back;
			}
		}
	}
	//搜索链表的元素 返回pos  下标从1开始 OK
	public int searchItem(int data)
	{
		if(first == null)
		{
			System.out.println("空链表!");
			return 0;
		}else{
			DNode current = first;
			int dataPos = 0;
			while(current.data!=data&¤t.next!=null)
			{
				current = current.next;
				this.pos++;
			}
			if(current.data == data)
			{
				dataPos = this.pos;
				this.pos = 1;
				return dataPos;
			}else{
				System.out.println("不存在该元素!");
				this.pos = 1;
				return 0;
			}
			
		}
		
	}
	//向链表中插入元素 下标从1之后开始
	public boolean insertNodeByPos(int pos, int data)
	{
		boolean flag = false;
		DNode newnode = new  DNode(data);
		DNode current=null,prior=null;
		if(pos<=1||pos>count+1)
		{
			System.out.println("Pos error!");
			return flag;
		}
		if(pos==count+1){ //在末尾插入节点
			newnode.back = last;
			last.next = newnode;
			last = newnode;
			count++;
			flag = true;
		}else //在其他位置插入节点
		{
			current = first;
			prior = first;
			while(this.pos<pos)
			{
				prior = current;
				current = current.next;
				this.pos++;
			}
			
				prior.next = newnode;
				newnode.back = prior;
				newnode.next = current;
				current.back = newnode;
				this.count++;
				this.pos = 1;
				flag = true;
			
	
		}
		return flag;
	}
	//在链表前插入元素
	public void addFirstNode(int data)
	{
		DNode newnode = new DNode(data);
		if(first == null)
		{
			first = newnode;
			last = newnode;
			count++;
		}else{
			newnode.next = first;
			first.back = newnode;
			first = newnode;
			count++;
		}
	}
	//在链表后插入元素
	public void addLastNode(int data)
	{
		DNode newnode = new DNode(data);
		
		if(first==null)
		{
			first = newnode;
			last = newnode;
			count++;
		}else{
			newnode.back = last;
			last.next = newnode;
			last = newnode;
			count++;
		}
		
	}
	//删除指定位置的元素
	public boolean deleteNodeByPos(int pos)
	{
		boolean flag = false;
		if(pos<1||pos>count)
		{
			System.out.println("pos error!");
			return flag;
		}
		if(pos==1){ //删除首节点
			if(count==1)  //只有一个节点 删除之
			{
				first = null;
				last = null;
				count--;
				flag = true;
			}else{  //大于一个节点 删除首节点
				DNode second = first.next;
				first = first.next;
				second.back = null;
				count--;
				flag = true;
			}
		}else if(pos == count){ //删除尾节点
			if(count==1)  //只有一个节点 删除之
			{
				first = null;
				last = null;
				count--;
				flag = true;
			}else{  //大于一个节点 删除尾节点
				DNode lbnl = last.back; //倒数第二个节点
				last = lbnl;
				lbnl.next = null;
				count--;
				flag = true;
			}
		}else{  //删除除首尾节点的其他节点 从头开始搜索或者从最后开始搜索
			DNode current = first,prior = first;
			while(this.pos<pos)
			{
				prior = current;
				current = current.next;
				this.pos++;
			}
			DNode afterCurrent = current.next;
			prior.next = afterCurrent;
			afterCurrent.back = prior;
			count--;
			this.pos = 1;
			flag = true;
		}
		
		return flag;
	}
	//给定元素 删除指定节点 删除第一个出现的节点
	public boolean deleteNodeByData(int data)
	{
		boolean flag = false;
		if(first==null)
		{
			System.out.println("空链表,无法删除!");
			return flag;
		}
		else{
			DNode current = first,prior = first;
			while(current.data!=data&¤t.next!=null)
			{
				prior = current;
				current = current.next;
				this.pos++;
			}
			if(this.pos==1) //首节点
			{
				DNode second = first.next;
				first = first.next;
				second.back = null;
				count--;
				flag = true;
			}else if(this.pos == count)//尾节点
			{
				if(current.data==data)
				{
					DNode lbnl = last.back; //倒数第二个节点
					last = lbnl;
					lbnl.next = null;
					count--;
					flag = true;
				}else{ //未找到
					System.out.println("未找到该元素!");
					flag = false;
				}		
			}else{
				DNode afterCurrent = current.next;
				prior.next = afterCurrent;
				afterCurrent.back = prior;
				count--;
				this.pos = 1;
				flag = true;
			}
		}
		return flag;
	}
}


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值