如何在Java中利用棧來反轉鏈表?針對這個問題,這篇文章詳細介紹了相對應的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。
棧是一個特殊的數據結構,特點是先進后出(First In Last Out 簡稱FILO),這種特殊的數據結構,可以用在對鏈表做反轉中,或者字符串逆序,因為要把頭變成尾,尾變成頭,棧這種結構最合適不過了,下面來看看如何用棧來做鏈表的反轉。
package com.xxx.algorithm.sort;
import java.util.Stack;
public class LinkedListReverse {
public static Node reverseLinkedList(Node head){
Stack<Node> stack = new Stack<Node>();
while(head!=null){
stack.push(head);
head = head.next;
}
if(!stack.isEmpty())
head = stack.pop();
Node cur = head;
while(!stack.isEmpty()){
Node node = stack.pop();
node.next = null;
cur.next = node;
cur = node;
}
return head;
}
public static void display(Node head){
System.out.print("list:");
Node cur = head;
while(cur!=null){
System.out.print(cur+"->");
cur = cur.next;
}
System.out.println();
}
public static void main(String[] args) {
Node a = new Node("a");
Node b = new Node("b");
Node c = new Node("c");
Node d = new Node("d");
Node e = new Node("e");
Node f = new Node("f");
Node g = new Node("g");
a.next = b;
b.next = c;
c.next = d;
d.next = e;
e.next = f;
f.next = g;
System.out.println("原始鏈表:");
display(a);
Node head = reverseLinkedList(a);
System.out.println("反轉之后的鏈表:");
display(head);
}
}
class Node{
String val;
Node next;
public Node(String val) {
this.val = val;
}
@Override
public String toString() {
return "Node("+this.val+")";
}
}原始鏈表:
list:Node(a)->Node(b)->Node(c)->Node(d)->Node(e)->Node(f)->Node(g)->
反轉之后的鏈表:
list:Node(g)->Node(f)->Node(e)->Node(d)->Node(c)->Node(b)->Node(a)->
通過棧來反轉鏈表思路很簡單,這只是說了棧作為一種數據結構,其實用途很廣泛。今天要介紹的另外一個棧的用途是如何通過棧來排序,利用棧來排序,需要有兩個棧,一個存放原始數據,一個是輔助排序用的。
具體思路就是:將棧中的數據依次放入輔助棧中,放入輔助棧的要求是按照數據從大到小的排列(或者從小到大),先進入的是較大的數,后進入的是較小的數,如果原棧中沒有數據了,說明數據已經在輔助棧中排好序了,接著我們把數據再一次性放入原棧中,如果遍歷,就是一個排好序的數組了。
這里面把原棧中的數據放入輔助棧中,需要借助一個中間變量,原棧中彈出的數據放入中間變量中,而不是直接入輔助棧,如果棧頂的元素小于中間變量,那么將小于的數據再放入原棧中,再將中間變量放入輔助棧,接著再將原棧中的數據放入輔助棧,直到原棧為空。將中間變量放入輔助棧,類似插入排序,需要找到一個合適的位置,而移動出一個合適的位置,就是把輔助棧中的數據再次壓入原棧中。
package com.xxx.algorithm.sort;
import java.util.Iterator;
import java.util.Stack;
public class StackSortDemo {
public static void sortByStack(Stack<Integer> stack){
Stack<Integer> help = new Stack<Integer>();
while(!stack.isEmpty()){
int cur = stack.pop();
while(!help.isEmpty()&&help.peek()<cur){
stack.push(help.pop());
}
help.push(cur);
}
while(!help.isEmpty()){
stack.push(help.pop());
}
}
public static void display(Stack<Integer> stack){
System.out.print("stack:");
Iterator<Integer> it = stack.iterator();
while(it.hasNext()){
System.out.print(it.next()+"->");
}
System.out.print("null");
System.out.println();
}
public static void main(String[] args) {
Stack<Integer> stack = new Stack<Integer>();
stack.push(2);
stack.push(9);
stack.push(5);
stack.push(4);
stack.push(6);
stack.push(3);
stack.push(8);
stack.push(7);
System.out.println("原始棧:");
display(stack);
sortByStack(stack);
System.out.println("排序之后的棧:");
display(stack);
}
}原始棧:
stack:2->9->5->4->6->3->8->7->null
排序之后的棧:
stack:2->3->4->5->6->7->8->9->null
補充:Java數據結構與算法-------鏈表反轉(如何實現鏈表的逆序)
鏈表 head -->1-->2-->3-->4-->5-->6-->7, 如何反轉為head -->7-->6->5-->4-->3-->2-->1,
思路:從鏈表的第二個節點開始,把遍歷到的節點插入到頭結點的后面,直到遍歷結束。
假設原鏈表:head -->1-->2-->3-->4-->5-->6-->7,
在遍歷2的時候,鏈表變為head -->2-->1-->3-->4-->5-->6-->7,
package LinkedList.Reverse;
/*
這里使用插入法進行反轉鏈表
思路:從鏈表的第二個節點開始,把遍歷到的節點插入到頭結點的后面,直到遍歷結束。
假設原鏈表:head -->1-->2-->3-->4-->5-->6-->7,
在遍歷2的時候,鏈表變為head -->2-->1-->3-->4-->5-->6-->7,
*/
public class Reverse {
public static void main(String[] args) {
//定義頭結點
LNode head=new LNode();
head.next=null;
LNode temp=null;
LNode cur=head;
//構造鏈表
for (int i = 1; i < 8; i++) {
temp=new LNode(); //定義一個輔助節點
temp.data=i; //temp數據為I
temp.next=null;
cur.next=temp; //頭結點的下一個節點為temp
cur=temp; //cur后移 由head移動到temp
}
System.out.println("逆序前:");
for (cur=head.next;cur!=null;cur=cur.next){
System.out.println(cur.data+" ");
}
System.out.println("逆序后:");
Reverse(head);
for (cur=head.next;cur!=null;cur=cur.next){
System.out.println(cur.data+" ");
}
}
public static void Reverse(LNode head){
if (head==null || head.next==null){//如果頭結點為空,或者頭結點的下一個節點為空,鏈表不用反轉
return;
}
LNode cur=null;//定義一個當前節點
LNode next=null;//定義一個后繼節點
//讓當前節點指向第二個節點
cur=head.next.next;
//先把第一個節點設置成最后一個節點
head.next.next=null;
while (cur!=null){//如果當前節點不為空
next=cur.next;//先保存當前節點的后繼節點 如 2 的后面一個節點3 先保存起來
cur.next=head.next;// 就是把2 的下一個節點指向1
head.next=cur;//把頭結點指向2
cur=next; //將當前節點指向下一個 3
}
}
}
class LNode{
LNode next;
int data;
}//使用遞歸法
private static LNode RecursiveReverse(LNode head){
//如果鏈表為空或者鏈表只有一個元素
if (head==null || head.next==null){
return head;
}else {
//反轉后面的節點
LNode newHead = RecursiveReverse(head.next);
//把前面遍歷的節點加到后面節點逆序后鏈表的尾部
head.next.next=head;
head.next=null;
return newHead;
}
}
public static void Reverse(LNode head){
if (head==null){
return;
}
//獲取鏈表的第一個節點
LNode firstNode=head.next;
//對鏈表進行逆序
LNode newhead = RecursiveReverse(firstNode);
head.next=newhead;
}關于如何在Java中利用棧來反轉鏈表問題的解答就分享到這里了,希望以上內容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關注億速云行業資訊頻道了解更多相關知識。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。