Java實(shí)現(xiàn)單鏈表的各種操作
主要內(nèi)容:
- 單鏈表的基本操作
- 刪除重復(fù)數(shù)據(jù)
- 找到倒數(shù)第k個(gè)元素
- 實(shí)現(xiàn)鏈表的反轉(zhuǎn)
- 從尾到頭輸出鏈表
- 找到中間節(jié)點(diǎn)
- 檢測(cè)鏈表是否有環(huán)
- 在不知道頭指針的情況下刪除指定節(jié)點(diǎn)
- 如何判斷兩個(gè)鏈表是否相交并找出相交節(jié)點(diǎn)
直接上代碼,就是這么奔放~~~
package pers.ty.$1101datastructure;
import java.util.Hashtable;
/**
* @author Administrator
* 實(shí)現(xiàn)單鏈表的基本操作,增加刪除節(jié)點(diǎn)、排序、打印、計(jì)算長(zhǎng)度
*/
public class MyLinkedList {
Node head = null;//鏈表頭的作用
/**向鏈表中插入數(shù)據(jù)
* @param d:插入數(shù)據(jù)的內(nèi)容
*/
public void addNode(int d){
Node newNode=new Node(d);
if(head==null){
head=newNode;
return;
}
Node tmp=head;
while(tmp.next!=null){
tmp=tmp.next;
}
//add Node to end
tmp.next=newNode;
}
/**
* @param index:刪除第index個(gè)節(jié)點(diǎn)
* @return 成功返回true,失敗返回false
*/
public Boolean deleteNode(int index){
if(index<1||index>length()){
return false;//刪除元素位置不合理
}
//刪除鏈表中的第一個(gè)元素
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 true;
}
/**
* @return 返回鏈表的長(zhǎng)度length
*/
public int length(){
int length=0;
Node tmp=head;
while(tmp!=null){
length++;
tmp=tmp.next;
}
return length;
}
/**
* 對(duì)鏈表進(jìn)行排序
* @return 返回排序后的頭結(jié)點(diǎn)
*/
public Node orderList(){
Node nextNode=null;
int temp=0;
Node curNode=head;
while(curNode.next!=null){
nextNode=curNode.next;
while(nextNode!=null){
if(curNode.data>nextNode.data){
temp=curNode.data;
curNode.data=nextNode.data;
nextNode.data=temp;
}
nextNode=nextNode.next;
}
curNode=curNode.next;
}
return head;
}
/**
* 打印鏈表中所有數(shù)據(jù)
*/
public void printList(){
Node tmp=head;
while(tmp!=null){
System.out.print(tmp.data+" ");
tmp=tmp.next;
}
System.out.println();
}
/**
* 從鏈表中刪除數(shù)據(jù)的第一種方法
* 遍歷鏈表,把遍歷到的數(shù)據(jù)存到一個(gè)Hashtable中,在遍歷過程中若當(dāng)前訪問的值在Hashtable
* 中存在,則可以刪除
* 優(yōu)點(diǎn):時(shí)間復(fù)雜度低 缺點(diǎn):需要額外的存儲(chǔ)空間來(lái)保存已訪問過得數(shù)據(jù)
*/
public void deleteDuplecate1(){
Hashtable<Integer,Integer> table=new Hashtable<Integer,Integer>();
Node tmp=head;
Node pre=null;
while (tmp!=null) {
if(table.containsKey(tmp.data))
pre.next=tmp.next;
else{
table.put(tmp.data, 1);
pre=tmp;
}
tmp=tmp.next;
}
}
/**
* 從鏈表中刪除重復(fù)數(shù)據(jù)的第二種方法
* 雙重循環(huán)遍歷
* 優(yōu)缺點(diǎn)很明顯
*/
public void deleteDuplecate2(){
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;
}
}
/**
* @param k:找到鏈表中倒數(shù)第k個(gè)節(jié)點(diǎn)
* @return 該節(jié)點(diǎn)
* 設(shè)置兩個(gè)指針p1、p2,讓p2比p1快k個(gè)節(jié)點(diǎn),同時(shí)向后遍歷,當(dāng)p2為空,則p1為倒數(shù)第k個(gè)節(jié)點(diǎn)
*/
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-1; i++)
p2=p2.next;
while (p2.next!=null) {
p2=p2.next;
p1=p1.next;
}
return p1;
}
/**
* 實(shí)現(xiàn)鏈表的反轉(zhuǎn)
* @param head鏈表的頭節(jié)點(diǎn)
*/
public void 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;
}
/**
* 通過遞歸從尾到頭輸出單鏈表
* @param head
*/
public void printListReversely(Node head){
if(head!=null){
printListReversely(head.next);
System.out.print(head.data+" ");
}
}
/**
* 查詢單鏈表的中間節(jié)點(diǎn)
* 定義兩個(gè)指針,一個(gè)每次走一步,一個(gè)每次走兩步...
* @param head
* @return q為中間節(jié)點(diǎn)
*/
public Node searchMid(Node head){
Node q=head;
Node p=head;
while (p!=null&&p.next!=null&&p.next.next!=null) {
q=q.next;
p=p.next.next;
}
return q;
}
/**
* 在不知道頭指針的情況下刪除指定節(jié)點(diǎn)
* 鏈表尾節(jié)點(diǎn)無(wú)法刪除,因?yàn)閯h除后無(wú)法使其前驅(qū)節(jié)點(diǎn)的next指針置為空
* 其他節(jié)點(diǎn),可以通過交換這個(gè)節(jié)點(diǎn)與其后繼節(jié)點(diǎn)的值,然后刪除后繼節(jié)點(diǎn)
* @param n
* @return
*/
public boolean deleteNode(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;
return true;
}
/**
* 判斷兩個(gè)鏈表是否相交
* 如果兩個(gè)鏈表相交,則肯定有相同的尾節(jié)點(diǎn),遍歷兩個(gè)鏈表,記錄尾節(jié)點(diǎn),看是否相同
* @param h1鏈表1的頭節(jié)點(diǎn)
* @param h2鏈表2的頭結(jié)點(diǎn)
* @return 是否相交
*/
public boolean isIntersect(Node h1,Node h2){
if(h1==null||h2==null)
return false;
Node tail1=h1;
while (tail1.next!=null){
tail1=tail1.next;
}
Node tail2=h2;
while(tail2.next!=null){
tail2=tail2.next;
}
return tail1==tail2;
}
/**
* 找出相交的第一個(gè)節(jié)點(diǎn)
* @param h1
* @param h2
* @return
*/
public Node getFirstMeetNode(Node h1,Node h2){
if(h1==null||h2==null)
return null;
Node tail1=h1;
int len1=1;
while (tail1.next!=null){
tail1=tail1.next;
len1++;
}
Node tail2=h2;
int len2=1;
while(tail2.next!=null){
tail2=tail2.next;
len2++;
}
if(tail1!=tail2){
return null;
}
Node t1=h1;
Node t2=h2;
//找出較長(zhǎng)的鏈表先遍歷
if(len1>len2){
int d=len1-len2;
while(d!=0){
t1=t1.next;
d--;
}
}
if(len1<len2){
int d=len2-len1;
while(d!=0){
t2=t2.next;
d--;
}
}
while(t1!=t2){
t1=t1.next;
t2=t2.next;
}
return t1;
}
public static void main(String[] args) {
MyLinkedList list=new MyLinkedList();
}
}
以上就是本文的全部?jī)?nèi)容,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,同時(shí)也希望多多支持腳本之家!
- Java實(shí)現(xiàn)單鏈表反轉(zhuǎn)的多種方法總結(jié)
- Java如何實(shí)現(xiàn)單鏈表的增刪改查
- Java單鏈表反轉(zhuǎn)圖文教程
- java實(shí)現(xiàn)簡(jiǎn)單單鏈表
- 用JAVA實(shí)現(xiàn)單鏈表,檢測(cè)字符串是否是回文串
- Java單鏈表的簡(jiǎn)單操作實(shí)現(xiàn)教程
- Java 8實(shí)現(xiàn)任意參數(shù)的單鏈表
- Java 單鏈表數(shù)據(jù)結(jié)構(gòu)的增刪改查教程
- java實(shí)現(xiàn)單鏈表增刪改查的實(shí)例代碼詳解
- Java數(shù)據(jù)結(jié)構(gòu)之簡(jiǎn)單鏈表的定義與實(shí)現(xiàn)方法示例
- java 數(shù)據(jù)結(jié)構(gòu)單鏈表的實(shí)現(xiàn)
- Java實(shí)現(xiàn)單鏈表翻轉(zhuǎn)實(shí)例代碼
- java 實(shí)現(xiàn)單鏈表逆轉(zhuǎn)詳解及實(shí)例代碼
- Java單鏈表的實(shí)現(xiàn)代碼
- Java數(shù)據(jù)結(jié)構(gòu)之單鏈表詳解
相關(guān)文章
Java volatile的適用場(chǎng)景實(shí)例詳解
在本文里我們給大家整理了一篇關(guān)于Java volatile的適用場(chǎng)景實(shí)例內(nèi)容和知識(shí)點(diǎn),需要的朋友們可以學(xué)習(xí)下。2019-08-08
SpringBoot下RabbitMq實(shí)現(xiàn)定時(shí)任務(wù)
這篇文章主要為大家詳細(xì)介紹了SpringBoot下RabbitMq實(shí)現(xiàn)定時(shí)任務(wù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-11-11
Springboot關(guān)于自定義stater的yml無(wú)法提示問題解決方案
這篇文章主要介紹了Springboot關(guān)于自定義stater的yml無(wú)法提示問題及解決方案,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-06-06
Java實(shí)現(xiàn)刪除PDF中指定頁(yè)面
這篇文章主要為大家詳細(xì)介紹了如何使用一個(gè)免費(fèi)的國(guó)產(chǎn)Java庫(kù)來(lái)刪除PDF中的指定頁(yè)面或者刪除PDF中的空白頁(yè),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-11-11
Java靜態(tài)static關(guān)鍵字原理詳解
這篇文章主要介紹了Java靜態(tài)static關(guān)鍵字原理詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-12-12
ReentrantLock條件變量使多個(gè)線程順序執(zhí)行
這篇文章主要為大家介紹了ReentrantLock條件變量使多個(gè)線程順序執(zhí)行,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
Java四舍五入時(shí)保留指定小數(shù)位數(shù)的五種方式
這篇文章主要介紹了Java四舍五入時(shí)保留指定小數(shù)位數(shù)的五種方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下2020-09-09

