久久福利_99r_国产日韩在线视频_直接看av的网站_中文欧美日韩_久久一

您的位置:首頁技術(shù)文章
文章詳情頁

用JAVA實現(xiàn)單鏈表,檢測字符串是否是回文串

瀏覽:5日期:2022-08-20 14:24:31

一.需求

使用JAVA實現(xiàn)單鏈表,使用單鏈表檢測字符串是否是回文串

二.需求分析

回文串最重要的就是對稱,那么最重要的問題就是找到那個中心,用快指針每步走兩格,當他到達鏈表末端的時候,慢指針剛好到達中心,慢指針在遍歷過程中(快指針到達末端時)把走過的節(jié)點進行反向操作,此時從中位點分為前后兩部分,此時前半部分的指針開始往回指(取next的時候,取的是前一個節(jié)點),而慢指針繼續(xù)向前,跟前半部分的數(shù)據(jù)依次進行比對,當慢指針掃完整個鏈表,就可以判斷這是回文串,否則就提前退出,同時在前半部分往回遍歷的過程中將前半部分的指針重置成正向。

鏈表存在奇偶數(shù)情況。

奇數(shù)的時候,快指針遍歷到末端的時候,中點位即中間位置的點,此中位點下一個節(jié)點為后半部分比對開始的位置。偶數(shù)的時候,快指針遍歷到末端的時候,中點位置此時為下中位點,此中位點就是后半部分比對開始的位置。

三.代碼實現(xiàn)

1.單鏈表類封裝

public class ListNode<T> { /** * 根節(jié)點索引位置 */ private int foot; /** * 代表鏈表程度 */ private int count; /** * 標識根節(jié)點 */ private Node root; //鏈接點類,內(nèi)部方法實現(xiàn),外部使用 private class Node { //數(shù)據(jù)信息 private T data; //下一個節(jié)點引用 private Node next; public Node(T data) { this.data = data; } //添加節(jié)點 private void add(T data) { if (this.next == null) { //如果當前節(jié)點的next為null,直接創(chuàng)建一個新的節(jié)點 this.next = new Node(data); } else { //否則進行遞歸調(diào)用,直到最后在某個為空的節(jié)點創(chuàng)建一個新節(jié)點 this.next.add(data); } } //刪除節(jié)點1 public void remove(Node previous, int index) { if (ListNode.this.foot++ == index) { //this表示當前要刪除的節(jié)點 previous.next = this.next; this.next = null; ListNode.this.count--; return; } else { //遞歸刪除 this.next.remove(this, index); } } //刪除節(jié)點2 public void remove(Node previous, T data) { if (this.data.equals(data)) { previous.next = this.next; this.next = null; ListNode.this.count--; return; } else { if (this.next != null) { this.next.remove(this, data); } else { return; } } } //修改數(shù)據(jù) -- 新數(shù)據(jù)替換舊數(shù)據(jù) public void replace(T oldData, T newData) { if (this.data.equals(newData)) { this.data = newData; } else { //遞歸修改,尋找當前節(jié)點下一個節(jié)點,直到某個節(jié)點的值匹配入?yún)? this.next.replace(oldData, newData); } } //修改數(shù)據(jù) -- 利用索引修改 public void replace(int index, T newData) { if (ListNode.this.foot++ == index) { //找到了某個值的索引和傳入的索引相同,直接替換 this.data = newData; } else { this.next.replace(index, newData); } } //查詢 public T get(int index) { if (ListNode.this.foot++ == index) { return this.data; } else { return this.next.get(index); } } //鏈表是否包含某個節(jié)點 public boolean contains(T data) { //如果當前的這個data正好和傳入的data匹配 if (this.data.equals(data)) { return true; } else { //如果當前的這個不匹配,則需要查找下一個節(jié)點 if (this.next == null) { return false; } else { return this.next.contains(data); } } } } public ListNode() { } //檢查鏈表是否為空 public boolean isEmpty() { if (count == 0 || this.root == null) { return true; } else { return false; } } //獲取鏈表的長度 public int size() { return this.count; } //添加 public void add(T data) { if (this.isEmpty()) { //如果鏈表為空,新建一個節(jié)點 this.root = new Node(data); } else { this.root.add(data); } this.count++; } //刪除 -- 按照索引刪除 public void remove(int index) { if (this.isEmpty()) { return; } if (index < 0 || this.count <= index) { return; } if (index == 0) { //想要刪除根節(jié)點 Node temp = this.root; this.root = this.root.next; temp.next = null; this.count--; return; } else { this.foot = 0; this.root.remove(this.root, index); } } //根據(jù)傳入的數(shù)值刪除 public void remove(T data) { if (this.isEmpty()) { return; } //如果刪除的正好是根節(jié)點 if (this.root.data.equals(data)) { Node temp = this.root; this.root = this.root.next; temp.next = null; this.count--; return; } else { this.root.remove(this.root, data); } } //修改 -- 根據(jù)索引修改 public void replace(int index, T newData) { if (this.isEmpty()) { return; } if (index < 0 || this.count <= index) { return; } this.foot = 0; this.root.replace(index, newData); } //修改 -- 新老數(shù)據(jù)替換 public void replace(T oldData, T newData) { if (this.isEmpty()) { return; } this.root.replace(oldData, newData); } //查詢 --- 根據(jù)索引查找 public T get(int index) { if (this.isEmpty()) { return null; } this.foot = 0; return this.root.get(index); } //是否包含 public boolean contains(T data) { if (this.isEmpty()) { return false; } return this.root.contains(data); } //打印 toArray public Object[] toArray() { if (this.isEmpty()) { return null; } int count = this.count; Object[] retVal = new Object[count]; for (int i = 0; i < count; i++) { retVal[i] = this.get(i); } return retVal; }}

2.驗證的具體方法

boolean isPalindrome(ListNode.Node head) { if (head == null || head.next == null) { return true; } // ListNode.Node prev = null; //慢指針節(jié)點 ListNode.Node slow = head; //快指針節(jié)點 ListNode.Node fast = head; //奇數(shù)的中位節(jié)點或者是偶數(shù)的下中位節(jié)點 ListNode.Node middle = head; while (fast != null && fast.next != null) { //快指針每次移動2個節(jié)點 fast = fast.next.next; //慢指針每次移動1個節(jié)點 ListNode.Node next = slow.next; //前半部分的指針反向。反向后前半部分節(jié)點的next節(jié)點都是他的前一個節(jié)點 slow.next = prev; //當前的慢指針指向前一個節(jié)點 prev = slow; //下一個節(jié)點變?yōu)槁?jié)點 slow = next; //記錄中位節(jié)點 middle = slow; } //如果fast不是null,說明此時有奇數(shù)個節(jié)點,偶數(shù)個節(jié)點時fast為null //還沒有進行if處理之前slow節(jié)點和prev節(jié)點在奇偶數(shù)的情況下分別為 // a b c d c b a 此種情況下slow節(jié)點是d,prev節(jié)點是第1個c // a b c c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c if (fast != null) { //slow取中間節(jié)點的下一個節(jié)點,做為回文比較的起點 slow = slow.next; } //進行if處理結(jié)束之后,slow代表的是后半段的第一個節(jié)點,指針向后移動 //prev代表的是前半段的最后一個節(jié)點,指針向前移動 // a b c d c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c // a b c c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c //前半部分指針恢復正常處理。將下一個節(jié)點記錄下來 ListNode.Node next = middle; while (slow != null) { //進行數(shù)據(jù)比對。如果不相等則不是回文 if (slow.data != prev.data) { return false; } //前半部分當前節(jié)點 ListNode.Node current = prev; //prev向前取節(jié)點 prev = prev.next; //slow向后取節(jié)點 slow = slow.next; //前半部分指針恢復正常處理。 current.next = next; //本輪處理完之后,將next賦值為當前節(jié)點 next = current; } return true;}

四.代碼測試

public static void main(String[] args) { ListNode<String> listNode = new ListNode<String>(); listNode.add('a'); listNode.add('b'); listNode.add('c'); listNode.add('d'); listNode.add('e'); listNode.add('f'); listNode.add('e'); listNode.add('d'); listNode.add('c'); listNode.add('b'); listNode.add('a'); ListNode example = new ListNode(); boolean b = example.isPalindrome(listNode.root); System.out.println('是否是回文:' + b);//true}

五.完整代碼

public class ListNode<T> { /** * 根節(jié)點索引位置 */ private int foot; /** * 代表鏈表程度 */ private int count; /** * 標識根節(jié)點 */ private Node root; //鏈接點類,內(nèi)部方法實現(xiàn),外部使用 private class Node { //數(shù)據(jù)信息 private T data; //下一個節(jié)點引用 private Node next; public Node(T data) { this.data = data; } //添加節(jié)點 private void add(T data) { if (this.next == null) { //如果當前節(jié)點的next為null,直接創(chuàng)建一個新的節(jié)點 this.next = new Node(data); } else { //否則進行遞歸調(diào)用,直到最后在某個為空的節(jié)點創(chuàng)建一個新節(jié)點 this.next.add(data); } } //刪除節(jié)點1 public void remove(Node previous, int index) { if (ListNode.this.foot++ == index) { //this表示當前要刪除的節(jié)點 previous.next = this.next; this.next = null; ListNode.this.count--; return; } else { //遞歸刪除 this.next.remove(this, index); } } //刪除節(jié)點2 public void remove(Node previous, T data) { if (this.data.equals(data)) { previous.next = this.next; this.next = null; ListNode.this.count--; return; } else { if (this.next != null) { this.next.remove(this, data); } else { return; } } } //修改數(shù)據(jù) -- 新數(shù)據(jù)替換舊數(shù)據(jù) public void replace(T oldData, T newData) { if (this.data.equals(newData)) { this.data = newData; } else { //遞歸修改,尋找當前節(jié)點下一個節(jié)點,直到某個節(jié)點的值匹配入?yún)? this.next.replace(oldData, newData); } } //修改數(shù)據(jù) -- 利用索引修改 public void replace(int index, T newData) { if (ListNode.this.foot++ == index) { //找到了某個值的索引和傳入的索引相同,直接替換 this.data = newData; } else { this.next.replace(index, newData); } } //查詢 public T get(int index) { if (ListNode.this.foot++ == index) { return this.data; } else { return this.next.get(index); } } //鏈表是否包含某個節(jié)點 public boolean contains(T data) { //如果當前的這個data正好和傳入的data匹配 if (this.data.equals(data)) { return true; } else { //如果當前的這個不匹配,則需要查找下一個節(jié)點 if (this.next == null) { return false; } else { return this.next.contains(data); } } } } public ListNode() { } //檢查鏈表是否為空 public boolean isEmpty() { if (count == 0 || this.root == null) { return true; } else { return false; } } //獲取鏈表的長度 public int size() { return this.count; } //添加 public void add(T data) { if (this.isEmpty()) { //如果鏈表為空,新建一個節(jié)點 this.root = new Node(data); } else { this.root.add(data); } this.count++; } //刪除 -- 按照索引刪除 public void remove(int index) { if (this.isEmpty()) { return; } if (index < 0 || this.count <= index) { return; } if (index == 0) { //想要刪除根節(jié)點 Node temp = this.root; this.root = this.root.next; temp.next = null; this.count--; return; } else { this.foot = 0; this.root.remove(this.root, index); } } //根據(jù)傳入的數(shù)值刪除 public void remove(T data) { if (this.isEmpty()) { return; } //如果刪除的正好是根節(jié)點 if (this.root.data.equals(data)) { Node temp = this.root; this.root = this.root.next; temp.next = null; this.count--; return; } else { this.root.remove(this.root, data); } } //修改 -- 根據(jù)索引修改 public void replace(int index, T newData) { if (this.isEmpty()) { return; } if (index < 0 || this.count <= index) { return; } this.foot = 0; this.root.replace(index, newData); } //修改 -- 新老數(shù)據(jù)替換 public void replace(T oldData, T newData) { if (this.isEmpty()) { return; } this.root.replace(oldData, newData); } //查詢 --- 根據(jù)索引查找 public T get(int index) { if (this.isEmpty()) { return null; } this.foot = 0; return this.root.get(index); } //是否包含 public boolean contains(T data) { if (this.isEmpty()) { return false; } return this.root.contains(data); } //打印 toArray public Object[] toArray() { if (this.isEmpty()) { return null; } int count = this.count; Object[] retVal = new Object[count]; for (int i = 0; i < count; i++) { retVal[i] = this.get(i); } return retVal; } boolean isPalindrome(ListNode.Node head) { if (head == null || head.next == null) { return true; } // ListNode.Node prev = null; //慢指針節(jié)點 ListNode.Node slow = head; //快指針節(jié)點 ListNode.Node fast = head; //奇數(shù)的中位節(jié)點或者是偶數(shù)的下中位節(jié)點 ListNode.Node middle = head; while (fast != null && fast.next != null) { //快指針每次移動2個節(jié)點 fast = fast.next.next; //慢指針每次移動1個節(jié)點 ListNode.Node next = slow.next; //前半部分的指針反向。反向后前半部分節(jié)點的next節(jié)點都是他的前一個節(jié)點 slow.next = prev; //當前的慢指針指向前一個節(jié)點 prev = slow; //下一個節(jié)點變?yōu)槁?jié)點 slow = next; //記錄中位節(jié)點 middle = slow; } //如果fast不是null,說明此時有奇數(shù)個節(jié)點,偶數(shù)個節(jié)點時fast為null //還沒有進行if處理之前slow節(jié)點和prev節(jié)點在奇偶數(shù)的情況下分別為 // a b c d c b a 此種情況下slow節(jié)點是d,prev節(jié)點是第1個c // a b c c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c if (fast != null) { //slow取中間節(jié)點的下一個節(jié)點,做為回文比較的起點 slow = slow.next; } //進行if處理結(jié)束之后,slow代表的是后半段的第一個節(jié)點,指針向后移動 //prev代表的是前半段的最后一個節(jié)點,指針向前移動 // a b c d c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c // a b c c b a 此種情況下slow節(jié)點是第2個c,prev節(jié)點是第1個c //前半部分指針恢復正常處理。將下一個節(jié)點記錄下來 ListNode.Node next = middle; while (slow != null) { //進行數(shù)據(jù)比對。如果不相等則不是回文 if (slow.data != prev.data) { return false; } //前半部分當前節(jié)點 ListNode.Node current = prev; //prev向前取節(jié)點 prev = prev.next; //slow向后取節(jié)點 slow = slow.next; //前半部分指針恢復正常處理。 current.next = next; //本輪處理完之后,將next賦值為當前節(jié)點 next = current; } return true; } public static void main(String[] args) { ListNode<String> listNode = new ListNode<String>(); listNode.add('a'); listNode.add('b'); listNode.add('c'); listNode.add('d'); listNode.add('e'); listNode.add('f'); listNode.add('e'); listNode.add('d'); listNode.add('c'); listNode.add('b'); listNode.add('a'); ListNode example = new ListNode(); boolean b = example.isPalindrome(listNode.root); System.out.println('是否是回文:' + b); }}

以上就是使用JAVA實現(xiàn)單鏈表,檢測字符串是否是回文串的詳細內(nèi)容,更多關(guān)于java封裝單鏈表的資料請關(guān)注好吧啦網(wǎng)其它相關(guān)文章!

標簽: Java
主站蜘蛛池模板: 欧美日韩一区二区在线观看 | 久久精品123| 婷婷丁香综合 | 全黄大全大色全免费大片 | 99精品久久久 | 亚洲高清免费视频 | 黄色日本视频 | 啊v在线视频| 五月天婷婷国产精品 | 久久国内精品 | 欧美在线观看一区 | 亚洲免费国产视频 | 国产精品久久久久一区二区三区 | 国产精品日本一区二区不卡视频 | 久久久久久久久一区 | 欧美 日韩 亚洲 一区 | 国产精品夜间视频香蕉 | 日日摸日日碰夜夜爽亚洲精品蜜乳 | 欧美全黄 | 日本一二三区视频 | 成人免费视屏 | 久久精品在线观看视频 | 国产一区二区三区在线免费观看 | 五月色综合 | 精品国产一区二区三区久久久蜜 | 日韩在线观看视频一区二区三区 | 日本综合久久 | 四季久久免费一区二区三区四区 | 欧美成人精品一区二区男人看 | 午夜影院a| www.国产高清 | 女人久久久久 | 成人激情免费视频 | 欧美夜夜骑 | 人人爽在线观看 | 国产在线观 | 夜夜爽99久久国产综合精品女不卡 | 影音在线资源 | 一区二区三区视频 | 伊人在线 | 91精品国产91久久久久久吃药 |