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

Java實現單鏈表的各種操作

 更新時間:2016年12月23日 09:26:21   作者:一個弱者想變強  
本文主要對Java實現單鏈表的各種操作進行詳細介紹。具有很好的參考價值,需要的朋友一起來看下吧

主要內容:

  • 單鏈表的基本操作
  • 刪除重復數據
  • 找到倒數第k個元素
  • 實現鏈表的反轉
  • 從尾到頭輸出鏈表
  • 找到中間節(jié)點
  • 檢測鏈表是否有環(huán)
  • 在不知道頭指針的情況下刪除指定節(jié)點
  • 如何判斷兩個鏈表是否相交并找出相交節(jié)點

直接上代碼,就是這么奔放~~~

package pers.ty.$1101datastructure;
import java.util.Hashtable;
/**
 * @author Administrator
 * 實現單鏈表的基本操作,增加刪除節(jié)點、排序、打印、計算長度
 */
public class MyLinkedList {
  Node head = null;//鏈表頭的作用
  /**向鏈表中插入數據
   * @param d:插入數據的內容
   */
  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個節(jié)點
   * @return 成功返回true,失敗返回false
   */
  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 true;
  }
  /**
   * @return 返回鏈表的長度length
   */
  public int length(){
    int length=0;
    Node tmp=head;
    while(tmp!=null){
      length++;
      tmp=tmp.next;
    }
    return length;
  }
  /**
   * 對鏈表進行排序
   * @return 返回排序后的頭結點
   */
  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;
  }
  /**
   * 打印鏈表中所有數據
   */
  public void printList(){
    Node tmp=head;
    while(tmp!=null){
      System.out.print(tmp.data+" ");
      tmp=tmp.next;
    }
    System.out.println();
  }
  /**
   * 從鏈表中刪除數據的第一種方法
   * 遍歷鏈表,把遍歷到的數據存到一個Hashtable中,在遍歷過程中若當前訪問的值在Hashtable
   * 中存在,則可以刪除
   * 優(yōu)點:時間復雜度低  缺點:需要額外的存儲空間來保存已訪問過得數據
   */
  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;
    }
  }
  /**
   * 從鏈表中刪除重復數據的第二種方法
   * 雙重循環(huán)遍歷
   * 優(yōu)缺點很明顯
   */
  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:找到鏈表中倒數第k個節(jié)點
   * @return 該節(jié)點
   * 設置兩個指針p1、p2,讓p2比p1快k個節(jié)點,同時向后遍歷,當p2為空,則p1為倒數第k個節(jié)點
   */
  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;
  }
  /**
   * 實現鏈表的反轉
   * @param head鏈表的頭節(jié)點
   */
  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é)點
   * 定義兩個指針,一個每次走一步,一個每次走兩步...
   * @param head
   * @return q為中間節(jié)點
   */
  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é)點
   * 鏈表尾節(jié)點無法刪除,因為刪除后無法使其前驅節(jié)點的next指針置為空
   * 其他節(jié)點,可以通過交換這個節(jié)點與其后繼節(jié)點的值,然后刪除后繼節(jié)點
   * @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;
  }
  /**
   * 判斷兩個鏈表是否相交
   * 如果兩個鏈表相交,則肯定有相同的尾節(jié)點,遍歷兩個鏈表,記錄尾節(jié)點,看是否相同
   * @param h1鏈表1的頭節(jié)點
   * @param h2鏈表2的頭結點
   * @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;
  }
  /**
   * 找出相交的第一個節(jié)點
   * @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;
    //找出較長的鏈表先遍歷
    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();
  }
}

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的幫助,同時也希望多多支持腳本之家!

相關文章

  • Java volatile的適用場景實例詳解

    Java volatile的適用場景實例詳解

    在本文里我們給大家整理了一篇關于Java volatile的適用場景實例內容和知識點,需要的朋友們可以學習下。
    2019-08-08
  • SpringBoot下RabbitMq實現定時任務

    SpringBoot下RabbitMq實現定時任務

    這篇文章主要為大家詳細介紹了SpringBoot下RabbitMq實現定時任務,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-11-11
  • Springboot關于自定義stater的yml無法提示問題解決方案

    Springboot關于自定義stater的yml無法提示問題解決方案

    這篇文章主要介紹了Springboot關于自定義stater的yml無法提示問題及解決方案,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-06-06
  • Java實現刪除PDF中指定頁面

    Java實現刪除PDF中指定頁面

    這篇文章主要為大家詳細介紹了如何使用一個免費的國產Java庫來刪除PDF中的指定頁面或者刪除PDF中的空白頁,感興趣的小伙伴可以跟隨小編一起學習一下
    2023-11-11
  • Spring boot將配置屬性注入到bean類中

    Spring boot將配置屬性注入到bean類中

    本篇文章主要介紹了Spring boot將配置屬性注入到bean類中,小編覺得挺不錯的,現在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-03-03
  • Java靜態(tài)static關鍵字原理詳解

    Java靜態(tài)static關鍵字原理詳解

    這篇文章主要介紹了Java靜態(tài)static關鍵字原理詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • ReentrantLock條件變量使多個線程順序執(zhí)行

    ReentrantLock條件變量使多個線程順序執(zhí)行

    這篇文章主要為大家介紹了ReentrantLock條件變量使多個線程順序執(zhí)行,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • Java四舍五入時保留指定小數位數的五種方式

    Java四舍五入時保留指定小數位數的五種方式

    這篇文章主要介紹了Java四舍五入時保留指定小數位數的五種方式,幫助大家更好的理解和使用Java,感興趣的朋友可以了解下
    2020-09-09
  • MyBatis中映射文件的使用案例代碼

    MyBatis中映射文件的使用案例代碼

    這篇文章主要介紹了MyBatis中映射文件的使用,本文結合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • 淺談Java8 判空新寫法

    淺談Java8 判空新寫法

    在開發(fā)過程中很多時候會遇到判空校驗,如果不做判空校驗則會產生NullPointerException異常,本文就來介紹一下Java8 判空新寫法,感興趣的可以了解一下
    2021-09-09

最新評論