數據結構學習與應用-鏈表

鏈表

概念

鏈表是一種物理存儲單元上非連續、非順序的存儲結構,數據元素的邏輯順序是經過鏈表中的指針鏈接次序實現的。面試

存儲結構

單向鏈表是一種線性表,其實是由節點(Node)組成的,每個鏈表都包含多個節點,節點又包含兩個部分,一個是數據域 data(儲存節點含有的信息),一個是引用域 next(儲存下一個節點或者上一個節點的地址)。其數據在內存中存儲是不連續的,它存儲的數據分散在內存中,每一個結點只能也只有它能知道下一個結點的存儲位置。由 N 個節點(Node)組成單向鏈表,每個 Node 記錄本Node的數據及下一個 Node。向外暴露的只有一個頭節點(Head),咱們對鏈表的全部操做,都是直接或者間接地經過其頭節點來進行的。算法

在這裏插入圖片描述

節點(Node)是由一個須要儲存的對象及對下一個節點的引用組成的。數組

在這裏插入圖片描述

特色

  1. 獲取數據麻煩,須要遍歷查找,比數組慢。O(n)
  2. 方便插入、刪除。O(1)

經常使用操做

1.節點Nodebash

public class LJLinkNode<T> {

	public LJLinkNode next;
	public T data;

	public LJLinkNode() {
		this.next = null;
		this.data = null;
	}

	public LJLinkNode(T data) {
		this.data = data;
		this.next = null;
	}

}
複製代碼

2.建立鏈表 在鏈表中有一個頭指針,它的next域用於指示鏈表第一個節點。ui

// 鏈表頭的引用 ,相似於頭指針
public LJLinkNode<T> headNode = new LJLinkNode<T>();
複製代碼

3.插入 在鏈表中插入一個節點,有尾插法,即在鏈表的尾部插入一個節點。首先須要判斷當前的鏈表是不是空鏈表,是的話就在頭節點進行插入,不是的話須要遍歷鏈表,到尾部進行插入節點:this

/**
	 * 插入一條數據
	 * 
	 * @param value
	 */
	public void add(T value) {
		// 若是是頭節點的話,在next指針域中插入
		if (headNode.next == null) {
			headNode.next = new LJLinkNode<>(value);
			return;
		}

		LJLinkNode<T> tempNode = headNode;
		while (tempNode.next != null) {
			tempNode = tempNode.next;
		}
		tempNode.next = new LJLinkNode<>(value);
	}
複製代碼

4.刪除一個節點spa

刪除一個指定位置上面的節點,首先須要遍歷到那個位置,而後將當前節點的前一個節點的next指向當前節點的後一個節點,即跳過當前節點。由於當前節點沒法獲取到它,所以就至關於刪除了。指針

/**
	 * 刪除指定index的一個節點
	 * 
	 * @param data
	 */
	public boolean del(int index) {

		// index下標越界
		if (index < 0 || index > length()) {
			return false;
		}

		// 刪除頭節點
		if (index == 1) {
			headNode = headNode.next;
			return true;
		}

		LJLinkNode<T> preNode = headNode;
		LJLinkNode<T> curNode = preNode.next;
		int i = 2;
		while (curNode != null) {
			if (i == index) {
				// 指向刪除節點的後一個節點
				preNode.next = curNode.next;
				break;
			}
			preNode = curNode;
			curNode = preNode.next;
			i++;
		}
		return true;
	}
複製代碼

5.鏈表長度code

鏈表長度很好理解,遍歷鏈表便可:cdn

/**
	 * 鏈表長度
	 * 
	 * @return
	 */
	public int length() {
		int i = 0;
		LJLinkNode<T> tempLinkNode = headNode;
		while (tempLinkNode.next != null) {
			i++;
			tempLinkNode = tempLinkNode.next;
		}
		return i;
	}
複製代碼

6.獲取指定位置上的鏈表節點

獲取到指定位置上的節點的話,須要遍歷到當前位置,而後獲取它的節點:

/**
	 * 獲取第index的節點
	 * 
	 * @param index
	 * @return
	 */
	public LJLinkNode<T> getIndexLinkNode(int index) {
		if (index < 0 || index > length()) {
			return null;
		}
		LJLinkNode<T> tempNode = headNode;
		int i = 0;
		while (tempNode != null) {
			if (index == i) {
				break;
			}
			i++;
			tempNode = tempNode.next;
		}
		return tempNode;
	}
複製代碼

以上即是鏈表的基本操做,插入,刪除等。在面試過程當中還會有其餘的算法,咱們拿出幾個來簡單說明一下鏈表的算法應用。

算法應用

1.合併兩個有序鏈表

將兩個有序鏈表合併爲一個新的有序鏈表並返回。新鏈表是經過拼接給定的兩個鏈表的全部節點組成的。

示例:

輸入:1->2->4, 1->3->4 輸出:1->1->2->3->4->4

來源:力扣(LeetCode) 連接:leetcode-cn.com/problems/me…

在這裏插入圖片描述
相關文章
相關標籤/搜索