Java實現(xiàn)鏈表的常見操作算法詳解
鏈表分為單鏈表,雙向鏈表和循環(huán)鏈表,是一種鏈?zhǔn)酱鎯Y(jié)構(gòu),由一個個結(jié)點鏈?zhǔn)綐?gòu)成,結(jié)點包含數(shù)據(jù)域和指針域,其中單鏈表是只有一個指向后驅(qū)結(jié)點的指針,雙向鏈表除頭結(jié)點和尾結(jié)點外,每個結(jié)點都有一個前驅(qū)指針和一個后繼指針,循環(huán)鏈表的尾結(jié)點的指針指向頭結(jié)點.
相比數(shù)組而言,鏈表的插入和刪除比較快,查詢慢.
本文主要以單鏈表為例,介紹下鏈表的常用算法操作.
單鏈表的結(jié)構(gòu):
在java語言中,鏈表的每個結(jié)點用Node類來表示:
package com.linkedlist; public class Node { private int data;// 結(jié)點數(shù)據(jù) private Node next;// 下一個結(jié)點 public Node(int data) { this.data = data; } public int getData() { return data; } public void setData(int data) { this.data = data; } public Node getNext() { return next; } public void setNext(Node next) { this.next = next; } }
定義一個鏈表操作類,里面包含常用的操作:
package com.linkedlist; import java.util.Hashtable; public class LinkedListOperator { private Node head = null;// 頭結(jié)點 // 在鏈表的末尾增加一個結(jié)點 private void addNode(int data) { Node newNode = new Node(data); if (head == null) { head = newNode; return; } Node temp = head; while (temp.getNext() != null) { temp = temp.getNext(); } temp.setNext(newNode); } // 打印鏈表結(jié)點 private void printLink() { Node curNode = head; while (curNode != null) { System.out.println(curNode.getData()); curNode = curNode.getNext(); } System.out.println("==========="); } // 求鏈表長度 private int getLength() { int len = 0; Node curNode = head; while (curNode != null) { len++; curNode = curNode.getNext(); } return len; } // 刪除某一個結(jié)點 private boolean delNode(int index) { if (index < 1) { return false; } if (index == 1) { head = head.getNext(); return true; } Node preNode = head; Node curNode = head.getNext(); int n = 1; while (curNode.getNext() != null) { if (n == index) { preNode.setData(curNode.getData()); preNode.setNext(curNode.getNext()); return true; } preNode = preNode.getNext(); curNode = curNode.getNext(); n++; } if (curNode.getNext() == null) { preNode.setNext(null); } return false; } // 鏈表排序:選擇排序法,從小到大 private void sortList() { Node curNode = head; while (curNode != null) { Node nextNode = curNode.getNext(); while (nextNode != null) { if (curNode.getData() > nextNode.getData()) { int temp = curNode.getData(); curNode.setData(nextNode.getData()); nextNode.setData(temp); } nextNode = nextNode.getNext(); } curNode = curNode.getNext(); } } // 去掉重復(fù)元素 private void distinctLink() { Hashtable<Integer, Integer> map = new Hashtable<Integer, Integer>(); Node curNode = head; Node preNode = null; while (curNode != null) { if (map.containsKey(curNode.getData())) { preNode.setData(curNode.getData()); preNode.setNext(curNode.getNext()); } else { map.put(curNode.getData(), 1); preNode = curNode; } curNode = curNode.getNext(); } } // 返回倒數(shù)第k個結(jié)點,定義兩個指針,第一個指針向前移動K-1次,之后兩個指針同時前進, // 當(dāng)?shù)谝粋€指針到達(dá)末尾時,第二個指針?biāo)诘奈恢眉礊榈箶?shù)第k個結(jié)點 private Node getReverNode(int k) { if (k < 1) { return null; } Node first = head; Node second = head; for (int i = 0; i < k - 1; i++) { first = first.getNext(); } while (first.getNext() != null) { first = first.getNext(); second = second.getNext(); } return second; } // 反轉(zhuǎn)鏈表 private void reserveLink() { Node preNode = null; Node curNode = head; Node tempNode = null; while (curNode != null) { tempNode = curNode.getNext(); curNode.setNext(preNode); preNode = curNode; curNode = tempNode; } head = preNode; } // 尋找鏈表的中間結(jié)點 private Node getMiddleNode() { Node slowNode = head; Node quickNode = head; while (slowNode.getNext() != null && quickNode.getNext() != null) { slowNode = slowNode.getNext(); quickNode = quickNode.getNext().getNext(); } return slowNode; } // 判斷鏈表是否有環(huán) private boolean isRinged() { if (head == null) { return false; } Node slowNode = head; Node quickNode = head; while (slowNode.getNext() != null && quickNode.getNext() != null) { slowNode = slowNode.getNext(); quickNode = quickNode.getNext().getNext(); if (slowNode.getData() == quickNode.getData()) { return true; } } return false; } // 刪除指定結(jié)點 private boolean delNode(Node node) { if (node.getNext() == null) { return false;// 在不知道頭結(jié)點的情況下,沒法刪除單鏈表的尾結(jié)點 } node.setData(node.getNext().getData()); node.setNext(node.getNext().getNext()); return true; } // 判斷兩個鏈表是否相交:相交的鏈表的尾結(jié)點相同 private boolean isCross(Node n1, Node n2) { while (n1.getNext() != null) { n1 = n1.getNext(); } while (n2.getNext() != null) { n2 = n2.getNext(); } if (n1.getData() == n2.getData()) { return true; } return false; } // 求相交鏈表的起始點 private Node getFirstCrossNode(LinkedListOperator l1, LinkedListOperator l2) { int len = l1.getLength() - l2.getLength(); Node n1 = l1.head; Node n2 = l2.head; if (len > 0) { for (int i = 0; i < len; i++) { n1 = n1.getNext(); } } else { for (int i = 0; i < len; i++) { n2 = n2.getNext(); } } while (n1.getData() != n2.getData()) { n1 = n1.getNext(); n2 = n2.getNext(); } return n1; } public static void main(String[] args) { LinkedListOperator llo = new LinkedListOperator(); llo.addNode(10); llo.addNode(4); llo.addNode(6); llo.addNode(8); llo.printLink(); // llo.delNode(4); // llo.sortList(); // llo.distinctLink(); // System.out.println(llo.getReverNode(3).getData()); // llo.reserveLink(); // System.out.println(llo.getMiddleNode().getData()); // System.out.println(llo.isRinged()); llo.delNode(llo.head.getNext().getNext()); llo.printLink(); } }
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Java鏈表中添加元素的原理與實現(xiàn)方法詳解
- Java實現(xiàn)刪除排序鏈表中的重復(fù)元素的方法
- java 數(shù)據(jù)結(jié)構(gòu)之刪除鏈表中的元素實例代碼
- java實現(xiàn)單鏈表增刪改查的實例代碼詳解
- Java數(shù)據(jù)結(jié)構(gòu)之鏈表、棧、隊列、樹的實現(xiàn)方法示例
- JAVA實現(xiàn)雙向鏈表的增刪功能的方法
- Java實現(xiàn)單向鏈表反轉(zhuǎn)
- java數(shù)據(jù)結(jié)構(gòu)之實現(xiàn)雙向鏈表的示例
- java實現(xiàn)單鏈表中是否有環(huán)的方法詳解
- java實現(xiàn)數(shù)據(jù)結(jié)構(gòu)單鏈表示例(java單鏈表)
- java單向鏈表的實現(xiàn)實例
- Java實現(xiàn)鏈表中元素的獲取、查詢和修改方法詳解
相關(guān)文章
SpringBoot詳解實現(xiàn)自定義異常處理頁面方法
SpringBoot是Spring全家桶的成員之一,是一種整合Spring技術(shù)棧的方式(或者說是框架),同時也是簡化Spring的一種快速開發(fā)的腳手架2022-06-06java使用itext導(dǎo)出PDF文本絕對定位(實現(xiàn)方法)
下面小編就為大家?guī)硪黄猨ava使用itext導(dǎo)出PDF文本絕對定位(實現(xiàn)方法)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-06-06java利用JEXL實現(xiàn)動態(tài)表達(dá)式編譯
這篇文章主要介紹了java利用JEXL實現(xiàn)動態(tài)表達(dá)式編譯,系統(tǒng)要獲取多個數(shù)據(jù)源的數(shù)據(jù),并進行處理,最后輸出多個字段。字段的計算規(guī)則一般是簡單的取值最多加一點條件判斷,下面是具體的實現(xiàn)方法2021-04-04基于resty?security的Api權(quán)限控制與事務(wù)支持
這篇文章主要為大家介紹了基于resty?security的Api權(quán)限控制與事務(wù)支持讓數(shù)據(jù)操作處于事務(wù)控制下,有需要的朋友可以借鑒參考下,希望能夠有所幫助2022-03-03Spring中事務(wù)用法示例及實現(xiàn)原理詳解
這篇文章主要給大家介紹了關(guān)于Spring中事務(wù)用法示例及實現(xiàn)原理的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11