先创建一个简单的实体类
class Data{
public int no;
public Data next;
public Data(int no) {
this.no = no;
}
@Override
public String toString() { //重写toString方法
return "Data [no=" + no + "]";
}
}
写一个简单的单链表类,完成单链表的添加、遍历功能、逆序打印功能
class SingleLinkedList{
private Data head = new Data(0); //单链表头节点
//向单链表中添加数据,默认添加到末尾
public void add(Data data) {
Data temp = head; //因为头节点不能动,创建辅助指针,用于遍历链表
while(temp.next != null) {
temp = temp.next;
}
temp.next = data;
}
//显示链表
public void show() {
if(head.next == null) {
System.out.println("链表为空");
return;
}
Data temp = head.next; //因为头节点不能动,创建辅助指针,用于遍历链表
while(temp != null) {
System.out.println(temp);
temp = temp.next;
}
}
/**
* 逆序打印单链表总共有三种方法
* 1、将单链表的数据添加在一个数组中,然后逆序遍历数组
* 2、将单链表的数据放入栈中,然后遍历栈
* 3、将单链表的数据存放的位置颠倒
*/
//用方法一必须知道链表中的数据有多少,写一个方法计算出链表的数据
public int size() {
if(head.next == null) {
return 0;
}
Data temp = head.next; //因为头节点不能动,创建辅助指针,用于遍历链表
int size = 0;
while(temp != null) {
size++;
temp = temp.next;
}
return size;
}
//方法一
public void reversePrintMethod1() {
if(head.next == null) {
System.out.println("链表为空");
return;
}
Data[] datas = new Data[size()];
Data temp = head.next; //因为头节点不能动,创建辅助指针,用于遍历链表
for(int i=0;i<size();i++) {
datas[i] = temp;
temp = temp.next;
if(temp == null) {
break;
}
}
for(int i=size()-1;i>=0;i--) {
System.out.println(datas[i]);
}
}
//方法二
public void reversePrintMethod2() {
if(head.next == null) {
System.out.println("链表为空");
return;
}
Stack<Data> stack = new Stack<Data>();
Data temp = head.next; //因为头节点不能动,创建辅助指针,用于遍历链表
while(temp != null) {
stack.push(temp);
temp = temp.next;
}
while(stack.size() > 0) {
System.out.println(stack.pop());
}
}
//方法三,该方法需要创建一个新的头节点,然后遍历链表,将链表的元素一次取出,放在新的节点的最前端
//需要注意的是,这个方法会改变链表原先的结构,所以一般不采取这种方法逆序打印单链表的元素
public void reversePrintMethod3() {
//当链表为空或者链表中只有一个节点时,无需逆序
if(head.next == null || head.next.next == null) {
return;
}
Data reverseHead = new Data(0);
Data temp = head.next; //因为头节点不能动,创建辅助指针,用于遍历链表
Data next = null; //用于存放节点的下一个节点
while(temp != null) {
next = temp.next; //将temp的下一个节点存放在next中,因为temp的next域将会被覆盖,所以提前用一个变量存储
temp.next = reverseHead.next; //将新节点的头节点的下一个节点,存放在temp.next中
reverseHead.next = temp; //再将temp节点放在头节点的next域中
temp = next; //将存储的temp.next的节点再赋值给temp,是temp后移,继续遍历链表
}
//将reverseHead头节点的下一个节点给head头节点的next域,使原先的链表形成一个节点颠倒的链表,再次遍历该链表就会完成逆序打印的功能
head.next = reverseHead.next;
}
}
主类
public class SingleLinkedListDemo {
public static void main(String[] args) {
Data data1 = new Data(1);
Data data2 = new Data(2);
Data data3 = new Data(3);
Data data4 = new Data(4);
SingleLinkedList linkedList = new SingleLinkedList();
linkedList.add(data1);
linkedList.add(data2);
linkedList.add(data3);
linkedList.add(data4);
System.out.println("链表本身的顺序:");
linkedList.show();//Data [no=1] Data [no=2] Data [no=3] Data [no=4]
System.out.println();
System.out.println("调用方法一后,链表的顺序是:");
linkedList.reversePrintMethod1();//Data [no=4] Data [no=3] Data [no=2] Data [no=1]
System.out.println();
System.out.println("调用方法二后,链表的顺序是:");
linkedList.reversePrintMethod2();//Data [no=4] Data [no=3] Data [no=2] Data [no=1]
System.out.println();
System.out.println("调用方法三后,链表的顺序是:");
linkedList.reversePrintMethod3();
linkedList.show();//Data [no=4] Data [no=3] Data [no=2] Data [no=1]
}
}
作者还是萌新,如果有不适当的地方请指出