java单链表节点翻转_Java数据结构01-链表基础(讲解+代码+面试题)
文章結構
鏈表
鏈表包含單鏈表,雙向鏈表,循環鏈表等等。相對于線性表,添加,刪除操作非常方便,因為不用移動大量的節點,只需要修改對應的前后節點指針即可。下面用一個具體實例來說明下這種結構。現在有一需求,是將具有不同編號,姓名,昵稱的人添加到系統中。首先需要創建節點,既然是鏈表,節點除了基本信息也要加入下一節點指針,方便計算機在內存中查找。
單向鏈表是通過指針構建的列表,基本結構就是頭節點+下一節點地址指針--->節點+下一節點地址指針--->尾節點。
單鏈表的基本代碼實現
在這里強推一波韓順平的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-链表基础(讲解+代码+面试题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: html 进入效果,用css3实现简单的
- 下一篇: java支持多线程吗_Java多线程之一