简单的算法(1)--从尾到头打印链表

目录

1、java实现

1.1、递归

1.1.1、测试(完整源码)

1.2、利用栈来实现

1.2.1、测试

2、C语言

2.1、先将链表反转,再从头输出(改变链表的结构)

2.2、利用栈的“先进后出”特性


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

猜你喜欢

转载自blog.csdn.net/qq_41603102/article/details/83790258