目录
1、java实现
链表的定义:
public class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
1.1、递归
public class Solution {
ArrayList<Integer> arrayList=new ArrayList<Integer>();
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
this.printListFromTailToHead(listNode.next);
arrayList.add(listNode.val);
}
return arrayList;
}
}
此方式虽然看起来简洁,如果链表很长时,就会导致函数的调用层级很深,有可能会导致函数栈溢出。
1.1.1、测试(完整源码)
import java.util.ArrayList;
/**
* @Auther: zj
* @Date: 2018/11/6 17:18
* @Description: 从尾到头打印链表
*/
public class t7 {
//测试
public static void main(String[] args) {
ListNode listNode = new ListNode( 1 );
listNode.next = new ListNode( 3 );
listNode.next.next = new ListNode( 5 );
ListNode head=listNode;
while (head!=null){
System.out.print( head.val+"->" );
head=head.next;
}
System.out.print( "\n" );
Solution s= new Solution();
System.out.println( s.printListFromTailToHead( listNode ) );
}
}
//定义链表
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//从尾到头打印链表
class Solution {
ArrayList<Integer> arrayList=new ArrayList<Integer>();
ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
if(listNode!=null){
this.printListFromTailToHead(listNode.next);
arrayList.add(listNode.val);
}
return arrayList;
}
}
1.2、利用栈来实现
//法2:利用栈来
public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<Integer>();
while(listNode!=null) {
stack.push(listNode.val);
listNode=listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while(!stack.isEmpty()){
arrayList.add(stack.pop());
}
return arrayList;
}
1.2.1、测试
import java.util.ArrayList;
import java.util.Stack;
/**
* @Auther: zj
* @Date: 2018/11/6 17:18
* @Description: 从尾到头打印链表
*/
public class t7 {
public static void main(String[] args) {
ListNode listNode = new ListNode( 1 );
listNode.next = new ListNode( 3 );
listNode.next.next = new ListNode( 5 );
ListNode head=listNode;
while (head!=null){
System.out.print( head.val+"->" );
head=head.next;
}
System.out.print( "\n" );
Solution s= new Solution();
System.out.println( s.printListFromTailToHead( listNode ) );
}
}
//定义链表
class ListNode {
int val;
ListNode next = null;
ListNode(int val) {
this.val = val;
}
}
//法2:利用栈来
class Solution {
ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
Stack<Integer> stack = new Stack<Integer>();
while(listNode!=null) {
stack.push(listNode.val);
listNode=listNode.next;
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
while(!stack.isEmpty()){
arrayList.add(stack.pop());
}
return arrayList;
}
}
2、C语言
与java类似
2.1、先将链表反转,再从头输出(改变链表的结构)
从头到尾输出比较简单,于是我们很自然地想到把链表中链接结点的指针反转过来,改变链表的方向,就可以从头到尾输出了。
#include<stdio.h>
#include<stdlib.h>
//链表的相关操作
//定义链表的结构
typedef struct LNode *PtrToLNode;
struct LNode {
int data;//数据域,用于存储数据
PtrToLNode Next;//指针,可以用来访问节点数据,也可以遍历,指向下一个节点
};
//初始化
PtrToLNode init(int n) {
PtrToLNode head,node,end;//定义头节点,普通节点,尾部节点;
head = (PtrToLNode)malloc(sizeof(struct LNode));
scanf("%d",&(head->data));//头指针赋值
end =head;
for(int i=0;i<n;i++) {//添加结点
node = (PtrToLNode)malloc(sizeof(struct LNode));
scanf("%d",&(node->data));
end->Next=node;
end=node;
}
end->Next = NULL;//结束创建
return head;
}
//反转单链表
PtrToLNode reverseLNode(PtrToLNode head) {
if(head==NULL||head->Next==NULL) //少于两个节点没有反转的必要
return head;
PtrToLNode p,q,r;
p= head;
q=head->Next;
head->Next=NULL;//旧的头指针是新的尾指针,next需要指向NULL
while(q) {
r=q->Next; //先保留下一个step要处理的指针
q->Next=p;//然后p q交替工作进行反向
p=q;
q=r;
}
head=p;// 最后q必然指向NULL,所以返回了p作为新的头指针
return head;
}
int main(void) {
int n=3;
PtrToLNode head = init(n);//链表初始化&&链表赋值
PtrToLNode node=head;
while(node!=NULL) {
printf("%d->",node->data);//打印链表
node = node->Next;
}
printf("\n反转链表:\n");
PtrToLNode end =reverseLNode(head);//反转链表
while(end!=NULL) {
printf("%d->",end->data);
end=end->Next;
}
return 0;
}
2.2、利用栈的“先进后出”特性
#include<stdio.h>
#include<stdlib.h>
//链表的相关操作
//定义链表的结构
typedef struct LNode *PtrToLNode;
struct LNode {
int data;//数据域,用于存储数据
PtrToLNode Next;//指针,可以用来访问节点数据,也可以遍历,指向下一个节点
};
//定义栈的结构
typedef struct StackNode *PtrToStack;
struct StackNode {
int data;
PtrToStack Next;
};
//链表初始化及赋值
PtrToLNode init(int n) {
PtrToLNode head,node,end;//定义头节点,普通节点,尾部节点;
head = (PtrToLNode)malloc(sizeof(struct LNode));
scanf("%d",&(head->data));//头指针赋值
end =head;
for(int i=0;i<n;i++) {//添加结点
node = (PtrToLNode)malloc(sizeof(struct LNode));
scanf("%d",&(node->data));
end->Next=node;
end=node;
}
end->Next = NULL;//结束创建
return head;
}
//栈的初始化
PtrToStack createStack() {
PtrToStack head;
head = (PtrToStack)malloc(sizeof(struct StackNode));
head->Next=NULL;
return head;
}
//判断栈是否为空
int IsEmpty(PtrToStack s) {
if(s->Next==NULL) {
return 1;
} else {
return 0;
}
}
//压栈
void Push(PtrToStack s,int X) {
PtrToStack tmp = (PtrToStack)malloc(sizeof(struct StackNode));
tmp->data=X;
tmp->Next=s->Next;
s->Next=tmp;
}
//出栈
int Pop(PtrToStack s) {//栈顶
PtrToStack FirstCell;
int tmp;
if(IsEmpty(s)) {
printf("该堆栈为空");
return -1;
} else {
FirstCell = s->Next;
tmp = FirstCell->data;
s->Next=FirstCell->Next;
free(FirstCell);
}
return tmp;
}
int main(void) {
int n=3;
PtrToLNode head = init(n);//链表初始化&&链表赋值
PtrToLNode node=head;
while(node!=NULL) {
printf("%d->",node->data);//打印链表
node = node->Next;
}
printf("\n利用栈反向输出链表:\n");
PtrToStack stack_head=createStack();
PtrToLNode bbb=head;
while(bbb!=NULL) {
printf("%d\n",bbb->data);
Push(stack_head,bbb->data);//入栈
bbb = bbb->Next;
}
PtrToStack stack_bbb=stack_head;
printf("\n打印栈:\n");
PtrToStack ccc=stack_head->Next;//剔除栈顶元素
while(ccc!=NULL) {
printf("%d->",ccc->data);
ccc = ccc->Next;
}
return 0;
}
非常简单的题目,就是容易错:p