鏈表原理及java實現(xiàn)的示例分析

這篇文章主要介紹了鏈表原理及java實現(xiàn)的示例分析,具有一定借鑒價值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

目前創(chuàng)新互聯(lián)建站已為上千家的企業(yè)提供了網站建設、域名、網頁空間、網站托管、企業(yè)網站設計、五通橋網站維護等服務,公司將堅持客戶導向、應用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。

一:單向鏈表基本介紹

鏈表是一種數據結構,和數組同級。比如,Java中我們使用的ArrayList,其實現(xiàn)原理是數組。而LinkedList的實現(xiàn)原理就是鏈表了。鏈表在進行循環(huán)遍歷時效率不高,但是插入和刪除時優(yōu)勢明顯。下面對單向鏈表做一個介紹。

單鏈表的概念

鏈表是最基本的數據結構,其存儲的你原理圖如下圖所示

鏈表原理及java實現(xiàn)的示例分析

上面展示的是一個單鏈表的存儲原理圖,簡單易懂,head為頭節(jié)點,他不存放任何的數據,只是充當一個指向鏈表中真正存放數據的第一個節(jié)點的作用,而每個節(jié)點中都有一個next引用,指向下一個節(jié)點,就這樣一節(jié)一節(jié)往下面記錄,直到最后一個節(jié)點,其中的next指向null。

鏈表有很多種,比如單鏈表,雙鏈表等等。我們就對單鏈表進行學習,其他的懂了原理其實是一樣的。

單向鏈表是一種線性表,實際上是由節(jié)點(Node)組成的,一個鏈表擁有不定數量的節(jié)點。其數據在內存中存儲是不連續(xù)的,它存儲的數據分散在內存中,每個結點只能也只有它能知道下一個結點的存儲位置。由N各節(jié)點(Node)組成單向鏈表,每一個Node記錄本Node的數據及下一個Node。向外暴露的只有一個頭節(jié)點(Head),我們對鏈表的所有操作,都是直接或者間接地通過其頭節(jié)點來進行的。

鏈表原理及java實現(xiàn)的示例分析

上圖中最左邊的節(jié)點即為頭結點(Head),但是添加節(jié)點的順序是從右向左的,添加的新節(jié)點會被作為新節(jié)點。最先添加的節(jié)點對下一節(jié)點的引用可以為空。引用是引用下一個節(jié)點而非下一個節(jié)點的對象。因為有著不斷的引用,所以頭節(jié)點就可以操作所有節(jié)點了。

下圖描述了單向鏈表存儲情況。存儲是分散的,每一個節(jié)點只要記錄下一節(jié)點,就把所有數據串了起來,形成了一個單向鏈表。

鏈表原理及java實現(xiàn)的示例分析

節(jié)點(Node)是由一個需要儲存的對象及對下一個節(jié)點的引用組成的。也就是說,節(jié)點擁有兩個成員:儲存的對象、對下一個節(jié)點的引用。下面圖是具體的說明:

鏈表原理及java實現(xiàn)的示例分析

二、單項鏈表的實現(xiàn)

package com.zjn.LinkAndQueue;
/**
 * 自定義鏈表設計
 * 
 * @author zjn
 *
 */
public class MyLink {
	Node head = null;
	// 頭節(jié)點
	/**
   * 鏈表中的節(jié)點,data代表節(jié)點的值,next是指向下一個節(jié)點的引用
   * 
   * @author zjn
   *
   */
	class Node {
		Node next = null;
		// 節(jié)點的引用,指向下一個節(jié)點
		int data;
		// 節(jié)點的對象,即內容
		public Node(int data) {
			this.data = data;
		}
	}
	/**
   * 向鏈表中插入數據
   * 
   * @param d
   */
	public void addNode(int d) {
		Node newNode = new Node(d);
		// 實例化一個節(jié)點
		if (head == null) {
			head = newNode;
			return;
		}
		Node tmp = head;
		while (tmp.next != null) {
			tmp = tmp.next;
		}
		tmp.next = newNode;
	}
	/**
   * 
   * @param index:刪除第index個節(jié)點
   * @return
   */
	public Boolean deleteNode(int index) {
		if (index < 1 || index > length()) {
			return false;
		}
		if (index == 1) {
			head = head.next;
			return true;
		}
		int i = 1;
		Node preNode = head;
		Node curNode = preNode.next;
		while (curNode != null) {
			if (i == index) {
				preNode.next = curNode.next;
				return true;
			}
			preNode = curNode;
			curNode = curNode.next;
			i++;
		}
		return false;
	}
	/**
   * 
   * @return 返回節(jié)點長度
   */
	public int length() {
		int length = 0;
		Node tmp = head;
		while (tmp != null) {
			length++;
			tmp = tmp.next;
		}
		return length;
	}
	/**
   * 在不知道頭指針的情況下刪除指定節(jié)點
   * 
   * @param n
   * @return
   */
	public Boolean deleteNode11(Node n) {
		if (n == null || n.next == null)
		      return false;
		int tmp = n.data;
		n.data = n.next.data;
		n.next.data = tmp;
		n.next = n.next.next;
		System.out.println("刪除成功!");
		return true;
	}
	public void printList() {
		Node tmp = head;
		while (tmp != null) {
			System.out.println(tmp.data);
			tmp = tmp.next;
		}
	}
	public static void main(String[] args) {
		MyLink list = new MyLink();
		list.addNode(5);
		list.addNode(3);
		list.addNode(1);
		list.addNode(2);
		list.addNode(55);
		list.addNode(36);
		System.out.println("linkLength:" + list.length());
		System.out.println("head.data:" + list.head.data);
		list.printList();
		list.deleteNode(4);
		System.out.println("After deleteNode(4):");
		list.printList();
	}
}

三、鏈表相關的常用操作實現(xiàn)方法

1. 鏈表反轉

/**
   * 鏈表反轉
   * 
   * @param head
   * @return
   */
  public Node ReverseIteratively(Node head) {
    Node pReversedHead = head;
    Node pNode = head;
    Node pPrev = null;
    while (pNode != null) {
      Node pNext = pNode.next;
      if (pNext == null) {
        pReversedHead = pNode;
      }
      pNode.next = pPrev;
      pPrev = pNode;
      pNode = pNext;
    }
    this.head = pReversedHead;
    return this.head;
  }

2. 查找單鏈表的中間節(jié)點

采用快慢指針的方式查找單鏈表的中間節(jié)點,快指針一次走兩步,慢指針一次走一步,當快指針走完時,慢指針剛好到達中間節(jié)點。

/**
   * 查找單鏈表的中間節(jié)點
   * 
   * @param head
   * @return
   */
  public Node SearchMid(Node head) {
    Node p = this.head, q = this.head;
    while (p != null && p.next != null && p.next.next != null) {
      p = p.next.next;
      q = q.next;
    }
    System.out.println("Mid:" + q.data);
    return q;
  }

3. 查找倒數第k個元素

采用兩個指針P1,P2,P1先前移K步,然后P1、P2同時移動,當p1移動到尾部時,P2所指位置的元素即倒數第k個元素 。

/**
   * 查找倒數 第k個元素
   * 
   * @param head
   * @param k
   * @return
   */
  public Node findElem(Node head, int k) {
    if (k < 1 || k > this.length()) {
      return null;
    }
    Node p1 = head;
    Node p2 = head;
    for (int i = 0; i < k; i++)// 前移k步
      p1 = p1.next;
    while (p1 != null) {
      p1 = p1.next;
      p2 = p2.next;
    }
    return p2;
  }

4. 對鏈表進行排序

/**
   * 排序
   * 
   * @return
   */
public Node orderList() {
	Node nextNode = null;
	int tmp = 0;
	Node curNode = head;
	while (curNode.next != null) {
		nextNode = curNode.next;
		while (nextNode != null) {
			if (curNode.data > nextNode.data) {
				tmp = curNode.data;
				curNode.data = nextNode.data;
				nextNode.data = tmp;
			}
			nextNode = nextNode.next;
		}
		curNode = curNode.next;
	}
	return head;
}

5. 刪除鏈表中的重復節(jié)點

/**
   * 刪除重復節(jié)點
   */
  public void deleteDuplecate(Node head) {
    Node p = head;
    while (p != null) {
      Node q = p;
      while (q.next != null) {
        if (p.data == q.next.data) {
          q.next = q.next.next;
        } else
          q = q.next;
      }
      p = p.next;
    }

  }

6. 從尾到頭輸出單鏈表,采用遞歸方式實現(xiàn)

/**
   * 從尾到頭輸出單鏈表,采用遞歸方式實現(xiàn)
   * 
   * @param pListHead
   */
  public void printListReversely(Node pListHead) {
    if (pListHead != null) {
      printListReversely(pListHead.next);
      System.out.println("printListReversely:" + pListHead.data);
    }
  }

7. 判斷鏈表是否有環(huán),有環(huán)情況下找出環(huán)的入口節(jié)點

/**
   * 判斷鏈表是否有環(huán),單向鏈表有環(huán)時,尾節(jié)點相同
   * 
   * @param head
   * @return
   */
  public boolean IsLoop(Node head) {
    Node fast = head, slow = head;
    if (fast == null) {
      return false;
    }
    while (fast != null && fast.next != null) {
      fast = fast.next.next;
      slow = slow.next;
      if (fast == slow) {
        System.out.println("該鏈表有環(huán)");
        return true;
      }
    }
    return !(fast == null || fast.next == null);
  }

  /**
   * 找出鏈表環(huán)的入口
   * 
   * @param head
   * @return
   */
  public Node FindLoopPort(Node head) {
    Node fast = head, slow = head;
    while (fast != null && fast.next != null) {
      slow = slow.next;
      fast = fast.next.next;
      if (slow == fast)
        break;
    }
    if (fast == null || fast.next == null)
      return null;
    slow = head;
    while (slow != fast) {
      slow = slow.next;
      fast = fast.next;
    }
    return slow;
  }

感謝你能夠認真閱讀完這篇文章,希望小編分享的“鏈表原理及java實現(xiàn)的示例分析”這篇文章對大家有幫助,同時也希望大家多多支持創(chuàng)新互聯(lián),關注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關知識等著你來學習!

新聞名稱:鏈表原理及java實現(xiàn)的示例分析
網站網址:http://bm7419.com/article22/jdjojc.html

成都網站建設公司_創(chuàng)新互聯(lián),為您提供外貿建站、手機網站建設、網站建設微信小程序、網站內鏈、搜索引擎優(yōu)化

廣告

聲明:本網站發(fā)布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創(chuàng)新互聯(lián)

h5響應式網站建設