Java 数据结构之双向链表

版权声明:聂CC~ https://blog.csdn.net/ncc1995/article/details/86719707

啊,写完了双端之后,双向就好写多了,重点是改变结点的next指向的时候,一定要一起把previous改了,并且要注意可能在last结点处进行指向修改时存在的的null情况。

package linkList;

/*
 * 结点定义
 */
class doublyNode{
	Object data;
	doublyNode next;
	doublyNode previous;
	
	public doublyNode(Object d) {
		this.data = d;
		this.next = null;
		this.previous = null;
	}
	
	public void display() {
		System.out.print(data + " ");
	}
}

/*
 * 写一个双向链表
 */
public class doublyList {
	doublyNode first;
	doublyNode last;
	
	public doublyList() {
		this.first = null;
		this.last = null;
	}
	
	/*
	 * 从头插入结点
	 */
	public void insertFirst(Object d) {
		doublyNode newNode = new doublyNode(d);
		
		if(isEmpty()) {
			last = newNode;
		}else {
			first.previous = newNode;
		}
		newNode.next = first;
		first = newNode;
	}
	
	/*
	 * 从尾部插入结点
	 */
	public void insertLast(Object d) {
		doublyNode newNode = new doublyNode(d);
		
		if(isEmpty()) {
			first = newNode;
		}else {
			last.next = newNode;
			//放外边试试
			newNode.previous = last;
		}	
		
		last = newNode;
	}
	
	
	/*
	 *双向链表的插入操作注意点 :
	 * (1) 通用的:采用方法为定位到location-1处,所以第一个位置的插入要单独操作
	 * (2) 此次采用的方法是遍历所有结点,找到对应位置后插入,返回。
	 * (3) 插入操作时,只需注意在尾部插入时last结点的变化,而不像删除时还要考虑
	 *     插入第一个结点时last的变化。
	 * (4) 当在尾部插入时,current.next为null,所以不需要改变其previous。
	 * (5) 改变next指向时,一定要同时改变previous指向。
	 */
	public void insertLoc(int loc, Object d) {
		int j = 1;
		doublyNode current = first;
		
		doublyNode newNode = new doublyNode(d);
		if(loc<1 || loc>length()+1) {
			System.out.println("The location is not exit!");
			return;
		}
		
		if(j == loc) {
			newNode.next = current;
			current.previous = newNode;
			first = newNode;
			return;
		}
		while(current != null) {
			if(j == loc-1) {
				System.out.println(current.data);
				newNode.next = current.next;

				if(current == last) {
					last = current.next;
				}else {
					current.next.previous = newNode;
				}
				//这条语句已经将current的next指向改变了,所以不能将else后面的语句写在它后面
				current.next = newNode;
				newNode.previous = current;
				return;
			}
			
			current = current.next;
			j++;
		}
	}
	
	/*
	 * 任意位置删除
	 */
	public void deleteLoc(int loc) {
		doublyNode current = first;
		int j = 1;
		
		if(loc<1 || loc>length()) {
			System.out.println("delete ERROR!");
			return;
		}
		
		if(j == loc) {
			if(first == last) {
				last = null;
			}
			//将current的值赋给first,first就把current的next,previous等等都继承了
			//所以要将first.previous改为null
			first = current.next;
			first.previous = null;
			return;
		}
		
		while(current.next != null) {
			if(j == loc-1) {
				if(current.next == last) {
					//改变last之前,last还是在和其它结点相连,
					//所以不改变last的话,还是会输出原来的链表
					//last = current.next;
					last = current;
				}else {
					current.next.next.previous = current;
				}
				current.next = current.next.next;
				return;
			}
			
			current = current.next;
			j++;
		}
	}
	
	/*
	 * 从头打印链表
	 */
	public void displayFirst() {
		doublyNode current = first;
		
		while(current != null) {
			current.display();
			current = current.next;
		}
		System.out.println();
	}
	
	/*
	 * 从尾部开始打印链表
	 */
	public void displayLast() {
		doublyNode current = last;
		
		while(current != null) {
			current.display();
			current = current.previous;
		}
		System.out.println();
	}
	
	public boolean isEmpty() {
		return (first == null);
	}
	
	public int length() {
		int length = 0;
		doublyNode temp = first;
		
		while(temp != null) {
			length++;
			temp = temp.next;
		}
		
		return length;
	}
	
	/*
	 * 测试双端链表
	 */
	public static void main(String[] args) {
		doublyList list = new doublyList();
		
		list.insertFirst(1);
		list.insertFirst("cc");
		list.insertFirst("hi");
		list.displayFirst();
		list.displayLast();
		list.deleteLoc(3);
		list.displayFirst();
		list.displayLast();
	}
}

猜你喜欢

转载自blog.csdn.net/ncc1995/article/details/86719707