欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

鏈表的原理及java實(shí)現(xiàn)代碼示例

 更新時(shí)間:2017年11月21日 16:04:05   作者:jianyuerensheng  
這篇文章主要介紹了鏈表的原理及java實(shí)現(xiàn)代碼示例,涉及單向鏈表的基本介紹,單向鏈表的Java實(shí)現(xiàn)代碼分享等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以參考下。

一:?jiǎn)蜗蜴湵砘窘榻B

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

單鏈表的概念

鏈表是最基本的數(shù)據(jù)結(jié)構(gòu),其存儲(chǔ)的你原理圖如下圖所示

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

鏈表有很多種,比如單鏈表,雙鏈表等等。我們就對(duì)單鏈表進(jìn)行學(xué)習(xí),其他的懂了原理其實(shí)是一樣的。

單向鏈表是一種線性表,實(shí)際上是由節(jié)點(diǎn)(Node)組成的,一個(gè)鏈表?yè)碛胁欢〝?shù)量的節(jié)點(diǎn)。其數(shù)據(jù)在內(nèi)存中存儲(chǔ)是不連續(xù)的,它存儲(chǔ)的數(shù)據(jù)分散在內(nèi)存中,每個(gè)結(jié)點(diǎn)只能也只有它能知道下一個(gè)結(jié)點(diǎn)的存儲(chǔ)位置。由N各節(jié)點(diǎn)(Node)組成單向鏈表,每一個(gè)Node記錄本Node的數(shù)據(jù)及下一個(gè)Node。向外暴露的只有一個(gè)頭節(jié)點(diǎn)(Head),我們對(duì)鏈表的所有操作,都是直接或者間接地通過(guò)其頭節(jié)點(diǎn)來(lái)進(jìn)行的。

上圖中最左邊的節(jié)點(diǎn)即為頭結(jié)點(diǎn)(Head),但是添加節(jié)點(diǎn)的順序是從右向左的,添加的新節(jié)點(diǎn)會(huì)被作為新節(jié)點(diǎn)。最先添加的節(jié)點(diǎn)對(duì)下一節(jié)點(diǎn)的引用可以為空。引用是引用下一個(gè)節(jié)點(diǎn)而非下一個(gè)節(jié)點(diǎn)的對(duì)象。因?yàn)橛兄粩嗟囊?,所以頭節(jié)點(diǎn)就可以操作所有節(jié)點(diǎn)了。

下圖描述了單向鏈表存儲(chǔ)情況。存儲(chǔ)是分散的,每一個(gè)節(jié)點(diǎn)只要記錄下一節(jié)點(diǎn),就把所有數(shù)據(jù)串了起來(lái),形成了一個(gè)單向鏈表。

節(jié)點(diǎn)(Node)是由一個(gè)需要儲(chǔ)存的對(duì)象及對(duì)下一個(gè)節(jié)點(diǎn)的引用組成的。也就是說(shuō),節(jié)點(diǎn)擁有兩個(gè)成員:儲(chǔ)存的對(duì)象、對(duì)下一個(gè)節(jié)點(diǎn)的引用。下面圖是具體的說(shuō)明:

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

package com.zjn.LinkAndQueue;
/**
 * 自定義鏈表設(shè)計(jì)
 * 
 * @author zjn
 *
 */
public class MyLink {
	Node head = null;
	// 頭節(jié)點(diǎn)
	/**
   * 鏈表中的節(jié)點(diǎn),data代表節(jié)點(diǎn)的值,next是指向下一個(gè)節(jié)點(diǎn)的引用
   * 
   * @author zjn
   *
   */
	class Node {
		Node next = null;
		// 節(jié)點(diǎn)的引用,指向下一個(gè)節(jié)點(diǎn)
		int data;
		// 節(jié)點(diǎn)的對(duì)象,即內(nèi)容
		public Node(int data) {
			this.data = data;
		}
	}
	/**
   * 向鏈表中插入數(shù)據(jù)
   * 
   * @param d
   */
	public void addNode(int d) {
		Node newNode = new Node(d);
		// 實(shí)例化一個(gè)節(jié)點(diǎn)
		if (head == null) {
			head = newNode;
			return;
		}
		Node tmp = head;
		while (tmp.next != null) {
			tmp = tmp.next;
		}
		tmp.next = newNode;
	}
	/**
   * 
   * @param index:刪除第index個(gè)節(jié)點(diǎn)
   * @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é)點(diǎn)長(zhǎng)度
   */
	public int length() {
		int length = 0;
		Node tmp = head;
		while (tmp != null) {
			length++;
			tmp = tmp.next;
		}
		return length;
	}
	/**
   * 在不知道頭指針的情況下刪除指定節(jié)點(diǎn)
   * 
   * @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();
	}
}

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

1. 鏈表反轉(zhuǎn)

/**
   * 鏈表反轉(zhuǎn)
   * 
   * @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é)點(diǎn)

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

/**
   * 查找單鏈表的中間節(jié)點(diǎn)
   * 
   * @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. 查找倒數(shù)第k個(gè)元素

采用兩個(gè)指針P1,P2,P1先前移K步,然后P1、P2同時(shí)移動(dòng),當(dāng)p1移動(dòng)到尾部時(shí),P2所指位置的元素即倒數(shù)第k個(gè)元素 。

/**
   * 查找倒數(shù) 第k個(gè)元素
   * 
   * @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. 對(duì)鏈表進(jìn)行排序

/**
   * 排序
   * 
   * @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. 刪除鏈表中的重復(fù)節(jié)點(diǎn)

/**
   * 刪除重復(fù)節(jié)點(diǎn)
   */
  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. 從尾到頭輸出單鏈表,采用遞歸方式實(shí)現(xiàn)

/**
   * 從尾到頭輸出單鏈表,采用遞歸方式實(shí)現(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é)點(diǎn)

/**
   * 判斷鏈表是否有環(huán),單向鏈表有環(huán)時(shí),尾節(jié)點(diǎn)相同
   * 
   * @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;
  }

總結(jié)

以上就是本文關(guān)于鏈表的原理及java實(shí)現(xiàn)代碼示例的全部?jī)?nèi)容,希望對(duì)大家有所幫助。感興趣的朋友可以繼續(xù)參閱本站:

Java編程實(shí)現(xiàn)遞增排序鏈表的合并

Java面試題-實(shí)現(xiàn)復(fù)雜鏈表的復(fù)制代碼分享

Java輸出鏈表倒數(shù)第k個(gè)節(jié)點(diǎn)

如有不足之處,歡迎留言指出。

相關(guān)文章

  • 基于HttpClient在HTTP協(xié)議接口測(cè)試中的使用(詳解)

    基于HttpClient在HTTP協(xié)議接口測(cè)試中的使用(詳解)

    下面小編就為大家?guī)?lái)一篇基于HttpClient在HTTP協(xié)議接口測(cè)試中的使用(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-10-10
  • SpringBoot webSocket實(shí)現(xiàn)發(fā)送廣播、點(diǎn)對(duì)點(diǎn)消息和Android接收

    SpringBoot webSocket實(shí)現(xiàn)發(fā)送廣播、點(diǎn)對(duì)點(diǎn)消息和Android接收

    這篇文章主要介紹了SpringBoot webSocket實(shí)現(xiàn)發(fā)送廣播、點(diǎn)對(duì)點(diǎn)消息和Android接收,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下。
    2017-03-03
  • 解決Mapper接口和mapper.xml的文件位置問(wèn)題

    解決Mapper接口和mapper.xml的文件位置問(wèn)題

    這篇文章主要介紹了解決Mapper接口和mapper.xml的文件位置問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2020-12-12
  • Mybatis讀取和存儲(chǔ)json類型數(shù)據(jù)的實(shí)現(xiàn)

    Mybatis讀取和存儲(chǔ)json類型數(shù)據(jù)的實(shí)現(xiàn)

    本文主要介紹了Mybatis讀取和存儲(chǔ)json類型數(shù)據(jù)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-06-06
  • SpringBoot中過(guò)濾器Filter+JWT令牌實(shí)現(xiàn)登錄驗(yàn)證

    SpringBoot中過(guò)濾器Filter+JWT令牌實(shí)現(xiàn)登錄驗(yàn)證

    本文主要介紹了SpringBoot中過(guò)濾器Filter+JWT令牌實(shí)現(xiàn)登錄驗(yàn)證,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2024-04-04
  • 淺談Springboot整合RocketMQ使用心得

    淺談Springboot整合RocketMQ使用心得

    本篇文章主要介紹了Springboot整合RocketMQ使用心得,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-01-01
  • 詳解APP微信支付(java后臺(tái)_統(tǒng)一下單和回調(diào))

    詳解APP微信支付(java后臺(tái)_統(tǒng)一下單和回調(diào))

    這篇文章主要介紹了APP微信支付(java后臺(tái)_統(tǒng)一下單和回調(diào)),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • Spring Cloud中使用Eureka的詳細(xì)過(guò)程

    Spring Cloud中使用Eureka的詳細(xì)過(guò)程

    Eureka 是 Netflix 開(kāi)源的一個(gè)服務(wù)發(fā)現(xiàn)組件,它在微服務(wù)架構(gòu)中扮演著重要的角色,這篇文章主要介紹了Spring Cloud中如何使用Eureka,需要的朋友可以參考下
    2024-07-07
  • log4j使用教程詳解(怎么使用log4j2)

    log4j使用教程詳解(怎么使用log4j2)

    Log4j 2的好處就不和大家說(shuō)了,如果你搜了2,說(shuō)明你對(duì)他已經(jīng)有一定的了解,并且想用它,所以這里直接就上手了
    2013-12-12
  • SpringBoot使用Spring Security實(shí)現(xiàn)登錄注銷功能

    SpringBoot使用Spring Security實(shí)現(xiàn)登錄注銷功能

    這篇文章主要介紹了SpringBoot使用Spring Security實(shí)現(xiàn)登錄注銷功能,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2020-09-09

最新評(píng)論