日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

java单链表节点翻转_Java数据结构01-链表基础(讲解+代码+面试题)

發布時間:2024/8/23 java 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 java单链表节点翻转_Java数据结构01-链表基础(讲解+代码+面试题) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

文章結構

  • 鏈表的概念/用處
  • 鏈表的基本代碼實現(韓順平Java數據結構網課)
  • 劍指offer上鏈表題目代碼實現(個人手敲,更精巧的答案可以參考官網)
  • 鏈表

    鏈表包含單鏈表,雙向鏈表,循環鏈表等等。相對于線性表,添加,刪除操作非常方便,因為不用移動大量的節點,只需要修改對應的前后節點指針即可。下面用一個具體實例來說明下這種結構。現在有一需求,是將具有不同編號,姓名,昵稱的人添加到系統中。首先需要創建節點,既然是鏈表,節點除了基本信息也要加入下一節點指針,方便計算機在內存中查找。

    單向鏈表是通過指針構建的列表,基本結構就是頭節點+下一節點地址指針--->節點+下一節點地址指針--->尾節點。

    單鏈表的基本代碼實現

    在這里強推一波韓順平的Java數據結構網課,講的由淺入深,筆記詳細。當然自己看視頻之后自己再寫才是正道。

    https://www.bilibili.com/video/av54029771?from=search&seid=15096936792873170656?www.bilibili.comclass HeroNode{public int no; //編號public String name; //姓名public String nickname;//昵稱public HeroNode next; //下一節點指針//構造器public HeroNode(int no, String name, String nickname) {this.no = no;this.name = name;this.nickname = nickname; }@Overridepublic String toString() {return "HeroNode [no = " + no + ", name " + name + ", nickname = " + nickname;}}

    下一步是創建鏈表類,包括一些基本操作方法

    class SingleLinkedList{//初始化頭節點,頭節點不動private HeroNode head = new HeroNode(0, "", "");//返回頭節點,方便后續操作public HeroNode getHead() {return head;}//添加節點內到單向鏈表//思路,當不考慮編號順序,找到當前鏈表的最后節點,將最后節點的next指向新節點public void add(HeroNode heroNode) {HeroNode temp = head;//遍歷鏈表,找到最后while(true) {if(temp.next == null) {break;}//如果沒有找到,將temp后移temp = temp.next;}temp.next = heroNode;}//按照順序添加public void addByOrder(HeroNode heroNode) {//頭節點不能動,通過輔助指針//單鏈表,因此temp在添加位置的前一個結點HeroNode temp = head;boolean flag = false; //編號是否存在while(true) {if(temp.next == null) {//鏈表最后break;}if(temp.next.no > heroNode.no) {//位置找到break;}else if(temp.next.no == heroNode.no){//編號存在flag = true; }temp = temp.next;}if(flag) {System.out.printf("編號%d存在", heroNode.no);}else {heroNode.next = temp.next;temp.next = heroNode;}}//更新鏈表,在找到序號的情況下進行更新public void update(HeroNode newHeroNode) {//根據no修改if(head.next == null) {System.out.println("鏈表為空");return;}HeroNode temp = head.next;boolean flag = false;while(true) {if(temp == null) {break;}if(temp.no == newHeroNode.no) {flag = true;break;}temp = temp.next;}if(flag) {temp.name = newHeroNode.name;temp.nickname = newHeroNode.nickname;}else {System.out.printf("沒找編號%d的值", newHeroNode.no);}}//刪除節點//head不動,找到被刪除節點的前一個public void del(int no) {HeroNode temp = head;boolean flag = false;while(true) {if(temp.next == null) {break;}if (temp.next.no == no) {flag = true;break;}temp = temp.next;}if(flag) {temp.next = temp.next.next;}else {System.out.printf("要刪除的節點%d不存在", no);}} }

    這里說下頭節點存在的意義:

    1.防止單鏈表是空的而設的,否則空鏈表頭指針就會指向null.

    2.方便插入表頭或者刪除第一個結點

    劍指offer涉及到的鏈表題目

    第一題:從尾到頭打印鏈表

    思路:遞歸,深入到最底層取出節點.val值后一層一層回退

    import java.util.ArrayList; public class Solution {ArrayList<Integer> list = new ArrayList<Integer>();public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {if(listNode != null){this.printListFromTailToHead(listNode.next);list.add(listNode.val);}return list;} }

    第二題:輸入一個鏈表,輸出該鏈表中倒數第k個結點。

    思路1 傳統法得到鏈表長度L,再從頭遍歷到L-k個

    思路2 快慢指針,慢指針距離快指針始終k,當快指針到最后的null時候,輸出慢指針

    代碼是思路2

    public class Solution {public ListNode FindKthToTail(ListNode head,int k) {//快慢指針ListNode fast = head;ListNode slow = head;for(int i = 0; i < k; i++){if(fast == null){return null;} fast = fast.next;}while(fast != null){fast = fast.next;slow = slow.next;}return slow;} }

    第三題:輸入一個鏈表,反轉鏈表后,輸出新鏈表的表頭。

    思路:本能反應是遍歷到最后,倒數第二,第三以此類推,但是這樣每次都遍歷一遍鏈表花銷太大。最清真的思路是采用頭插法,先建立一個新的頭節點,依次將鏈表中的節點插入到新頭節點后邊的第一個位置,以此類推。這里需要注意的是為了防止斷鏈,要建立額外指針來儲存當前插入點current在原鏈表的下一個節點。

    題外話:韓老師的視頻里面頭節點是沒有數據的,這個題目Head是有數據的,害得我提交很多次都不合格。下面這個是head無數據版本

    public class Solution {public ListNode ReverseList(ListNode head) {if(head.next == null || head.next.next == null) {return head;}//輔助指針,遍歷原來的鏈表ListNode cur = head.next.next;ListNode next = null; //指向cur的下一個節點 防止斷鏈ListNode reverseHead = null;while( cur != null) {next = cur.next;//暫時保存后面有用cur.next = reverseHead.next;//cur的下一個節點指向新鏈表的最前端reverseHead.next = cur;//cur連接到新的鏈表最頂端cur = next;}return reverseHead;} }

    下面這個是head有數據版本

    public class Solution {public ListNode ReverseList(ListNode head) {if(head==null)return null;ListNode pre = null;ListNode next = null;while(head!=null){next = head.next;head.next = pre;pre = head;head = next;}return pre;} }

    第四題:合并兩個有序鏈表

    /* public class ListNode {int val;ListNode next = null;ListNode(int val) {this.val = val;} }*/ public class Solution {public ListNode Merge(ListNode list1, ListNode list2) {if (list1 == null) {return list2;}if (list2 == null) {return list1;}ListNode temp = null;ListNode mergeHead = null;while (list1 != null && list2 != null) {if (list1.val < list2.val) {if (mergeHead == null) {mergeHead = list1;temp = list1;} else {temp.next = list1;temp = temp.next;}list1 = list1.next;} else {if (mergeHead == null) {mergeHead = list2;temp = list2;} else {temp.next = list2;temp = temp.next;}list2 = list2.next;}}if (list1 == null) {temp.next = list2;} else {temp.next = list1;}return mergeHead;} }

    總結

    以上是生活随笔為你收集整理的java单链表节点翻转_Java数据结构01-链表基础(讲解+代码+面试题)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。