【Java】 大話數據結構(5) 線性表之雙向鏈表

 

本文根據《大話數據結構》一書,實現了Java版的雙向鏈表html

在每一個數據結點中都有兩個指針,分別指向直接後繼和直接前驅,這樣的鏈表稱爲雙向鏈表java

雙向鏈表的結構如圖所示:node

 

  • 查找元素能夠根據元素的位置,分別沿正向和反向查找

雙向鏈表實現程序:數組

package DuLinkList;

public class DuLinkList<E> {
	private Node<E> head;
	private int count;

	/**
	 * 結點
	 */
	class Node<E> {
		E data;
		Node<E> prior;
		Node<E> next;

		public Node(E data, Node<E> prior, Node<E> next) {
			this.data = data;
			this.prior = prior;
			this.next = next;
		}
	}

	/**
	 * 線性表的初始化
	 */
	public DuLinkList() {
		head = new Node<E>(null, null, null);
		head.prior = head.next = head;
		count = 0;
	}

	/**
	 * 獲取第i個元素
	 */
	public Node<E> getElement(int i) {
		if (count == 0)
			throw new RuntimeException("空表,沒法查找!");
		if (i < 1 || i > count)
			throw new RuntimeException("查找位置錯誤!");
		Node<E> node = head.next;
		for (int j = 1; j < i; j++) {
			node = node.next;
		}
		return node;
	}

	/**
	 * 在第i個位置插入元素
	 */
	public void listInsert(int i, E data) {
		if (i < 1 || i > count + 1)
			throw new RuntimeException("插入位置錯誤!");
		Node<E> node = new Node<E>(data, null, null);
		if (i == 1) {
			node.next = head.next;
			node.prior = head;
			head.next.prior = node;
			head.next = node;
		} else {
			Node<E> pNode = getElement(i - 1);
			node.next = pNode.next;
			node.prior = pNode;
			pNode.next.prior = node;
			pNode.next = node;
		}
		count++;
	}

	/**
	 * 刪除第i個元素
	 */
	public E listDelete(int i) {
		if (i < 1 || i > count)
			throw new RuntimeException("刪除位置錯誤!");
		Node<E> node = getElement(i);
		E e = node.data;
		if (i == 1) {
			head.next = node.next;
			node.next.prior = node.prior;
			node = null;
		} else {
			node.next.prior = node.prior;
			node.prior.next = node.next;
			node = null;
		}
		count--;
		return e;
	}

	public int listLength() {
		return count;
	}

}

  

測試程序:數據結構

package DuLinkList;

public class DuLinkListTest {

	public static void main(String[] args) {
		DuLinkList<Student> students = new DuLinkList<Student>();
		System.out.println("——————————插入1到5,並讀取內容——————————");
		Student[] stus = { new Student("小A", 11), new Student("小B", 12), new Student("小C", 13), new Student("小D", 14),
				new Student("小E", 151) };
		for (int i = 1; i <= 5; i++)
			students.listInsert(i, stus[i - 1]);
		System.out.println("表長:" + students.listLength());
		Student stu;
		for (int i = 1; i <= 5; i++) {
			stu = students.getElement(i).data;
			System.out.println("第" + i + "個位置爲:" + stu.name);
		}
		System.out.println("——————————刪除小A、小E——————————");
		stu = students.listDelete(1);
		System.out.println("已刪除:" + stu.name);
		stu = students.listDelete(4);
		System.out.println("已刪除:" + stu.name);
		System.out.println("當前表長:" + students.listLength());
		for (int i = 1; i <= students.listLength(); i++) {
			stu = students.getElement(i).data;
			System.out.println("第" + i + "個位置爲:" + stu.name);
		}
	}
}

class Student {
	public Student(String name, int age) {
		this.name = name;
		this.age = age;
	}

	String name;
	int age;
}

  

——————————插入1到5,並讀取內容——————————
表長:5
第1個位置爲:小A
第2個位置爲:小B
第3個位置爲:小C
第4個位置爲:小D
第5個位置爲:小E
——————————刪除小A、小E——————————
已刪除:小A
已刪除:小E
當前表長:3
第1個位置爲:小B
第2個位置爲:小C
第3個位置爲:小D
DuLinkListTest

 

 

——————————————————————————ide

在閱讀過他人的博客後,發現本身的查找方法沒有利用好雙鏈表的特性,重寫查找方法以下:post

	/**
	 * 獲取第i個元素
	 */
	public Node<E> getElement(int i) {
		if (count == 0)
			throw new RuntimeException("空表,沒法查找!");
		if (i < 1 || i > count)
			throw new RuntimeException("查找位置錯誤!");
		if (i <= count / 2) { // 正向查找
			Node<E> node = head.next;
			for (int j = 1; j < i; j++) {
				node = node.next;
			}
			return node;
		} else {             // 反向查找
			Node<E> node = head.prior;
			int k = count - i;
			for (int j = 0; j < k; j++) {
				node = node.prior;
			}
			return node;
		}
	}

  

本文中只編寫了查找和刪除部分的程序,完整的雙向鏈表程序可參閱這篇博客:數組、單鏈表和雙鏈表介紹 以及 雙向鏈表的C/C++/Java實現測試

相關文章
相關標籤/搜索