从尾到头打印链表、数组操作、二叉树中序的下一个结点、用两个栈实现队列-Java基础

1. 从尾到头打印链表

 从尾到头反过来打印出每个结点的值。

解题思路

1)使用递归

要逆序打印链表 1->2->3(3,2,1),可以先逆序打印链表 2->3(3,2),最后再打印第一个节点 1。而链表 2->3 可以看成一个新的链表,要逆序打印该链表可以继续使用求解函数,也就是在求解函数中调用自己,这就是递归函数。

public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
    ArrayList<Integer> ret = new ArrayList<>();
    if (listNode != null) {
        ret.addAll(printListFromTailToHead(listNode.next));
        ret.add(listNode.val);
    }
    return ret;
}

2)使用栈

栈具有后进先出的特点,在遍历链表时将值按顺序放入栈中,最后出栈的顺序即为逆序。

剑指offer代码:

  1. import java.util.ArrayList;
  2. import java.util.Stack;
  3. /**
  4. *    public class ListNode {
  5. *        int val;
  6. *        ListNode next = null;
  7. *
  8. *        ListNode(int val) {
  9. *            this.val = val;
  10. *        }
  11. *    }
  12. *
  13. */
  14. import java.util.ArrayList;
  15. public class Solution {
  16.     public ArrayList<Integer> printListFromTailToHead(ListNode listNode) {
  17.          ArrayList<Integer> list = new  ArrayList<Integer> ();
  18.         Stack<Integer> stack = new Stack<Integer>();
  19.         while(listNode!=null)
  20.         {
  21.             stack.push(listNode.val);
  22.             listNode = listNode.next;
  23.         }
  24.        while(!stack.isEmpty())
  25.            list.add(stack.pop());
  26.         return list;
  27.     }
  28. }

本机跑的代码:

 

  1.     /**
  2.      * @param  ycy
  3.      */
  4.     public ArrayList<Integer> printListRever(ListNode listnode){   //使用栈完成倒叙
  5.         Stack stack = new Stack<Integer>();
  6.         while(listnode != null){
  7.             stack.add(listnode.val);
  8.             listnode = listnode.next;
  9.         }
  10.         ArrayList<Integer> ret = new ArrayList<Integer>();
  11.         while(!stack.isEmpty()){
  12.             ret.add((Integer) stack.pop());
  13.         }
  14.         return ret;
  15.         
  16.     }
  17.     class ListNode      //定义ListNode类
  18.     {
  19.         int val;
  20.         ListNode next;
  21.         
  22.         public ListNode(int x){
  23.             val=x;
  24.         }
  25.       
  26.     }
  27.          public ListNode addTwoNumbers(ListNode l1,ListNode l2){ //对ListNode进行添加操作
  28.                 ListNode dummyHead = new ListNode(0);
  29.                 ListNode p=l1,q=l2,curr=dummyHead;
  30.                 int carry=0;//进位
  31.                 while(p!=null || q!=null){
  32.                     int x=(p!=null)?p.val:0;
  33.                     int y=(q!=null)?q.val:0;
  34.                     int sum=x+y+carry;
  35.                     carry=sum/10;
  36.                     curr.next=new ListNode(sum%10);
  37.                     curr=curr.next;
  38.                     if(p!=null) p=p.next;
  39.                     if(q!=null) q=q.next;
  40.                 }
  41.                 if(carry>0){
  42.                     curr.next=new ListNode(carry);
  43.                 }
  44.                 
  45.                 return dummyHead.next;
  46.         }

 2 、数组的基本操作

  1. public class myArray {
  2.     /**
  3.      * @param ycy
  4.      */
  5.     private int[] arry;
  6.     private int elements=0;
  7.     public myArray(){
  8.         arry = new int[50];
  9.     }
  10.     public myArray(int maxsize){
  11.         arry = new int[maxsize];
  12.         
  13.     }
  14.     public void insert(int value){  //添加数据
  15.         arry[elements] = value;
  16.         elements++;
  17.     }
  18.     public void Orderinsert(int value){  //有序添加数据   初始化有序数组
  19.         int i;
  20.         for(i=0;i<elements;i++){
  21.             if(arry[i]>value){
  22.                 break;
  23.             }
  24.         }
  25.         for(int j=elements;j>i;j--){   //有序插入的时候,每次进行后移,当判断数据大于value的时候,则把数据插入到当前元素前面,当前元素之后的数据进行后移
  26.             arry[j] = arry[j-1];
  27.         }
  28.         arry[i] = value;
  29.         elements++;
  30.     }
  31.     public void display(){
  32.         System.out.print("{");
  33.         for(int i=0;i<elements;i++){
  34.             System.out.print(arry[i] + " ");
  35.         }
  36.         System.out.print("}");
  37.     }
  38.     public int search(int index){  //查找索引所对应的数据index >= elements || index < 0,不用落下等于号
  39.         if(index >= elements || index < 0){
  40.             return -1;
  41.         }else{
  42.             System.out.println(arry[index]);
  43.             return arry[index];
  44.         }
  45.         
  46.     }
  47.     public int searchIndex(int value){  //查找下标
  48.         for(int i=0;i<arry.length;i++){
  49.             if(arry[i]==value){
  50.                 return i;
  51.             }
  52.         }
  53.             return -1;
  54.     }
  55.     public void delete(int index){      //删除数据
  56.         if(index >= elements || index < 0){
  57.             throw new ArrayIndexOutOfBoundsException();
  58.         }else{
  59.             for(int i=index;i<elements;i++){  //删除数组中的一个数据,就是这个数据后面的数据进行前移
  60.                 arry[i] = arry[i+1];
  61.             }
  62.             elements--;
  63.         }
  64.     }
  65.     public void change(int index,int value){
  66.         
  67.         arry[index] = value;
  68.         
  69.     }
  70.     public int Binarysearch(int value){    //二分查找,针对有序的数组
  71.         int middle =0, low = 0, high = 0;
  72.         while(true){
  73.             middle = (low + high) / 2;
  74.             if(value == middle){
  75.                 return middle;
  76.             }else{
  77.                 if(arry[middle] > value){
  78.                     high = middle-1;
  79.                     for(int i=low;i<high;i++){
  80.                         if(arry[i] == value){
  81.                             return i;
  82.                         }
  83.                     }
  84.                 }else{
  85.                     low = middle+1;
  86.                     for(int i=low;i<elements;i++){
  87.                         if(arry[i] == value){
  88.                             return i;
  89.                         }
  90.                     }
  91.                 }
  92.             }
  93.             return -1;
  94.         }
  95.         
  96.         
  97.     }
  98.     public static void main(String[] args) {
  99.         // TODO Auto-generated method stub
  100.         myArray mya = new myArray();
  101.         mya.Orderinsert(12);
  102.         mya.Orderinsert(45);
  103.         mya.Orderinsert(432);
  104.         mya.Orderinsert(42);
  105.         
  106.         mya.display();
  107.         
  108.         System.out.println("索引是"+mya.searchIndex(42));
  109.         System.out.println("索引4的值是"+mya.search(4));
  110.         
  111.     //    mya.delete(1);
  112.         
  113.     //    mya.display();
  114.     //    mya.change(0, 4);
  115.     //    mya.display();
  116.         System.out.print(mya.Binarysearch(432));
  117.         
  118.     }
  119. }

3、二叉树的下一个结点

题目描述

给定一个二叉树和其中的一个结点,请找出中序遍历顺序的下一个结点并且返回。注意,树中的结点不仅包含左右子结点,同时包含指向父结点的指针。

解题思路

1)中序遍历:先左后根后右边

2)其中下一个节点包括:如果包含右子树,则是右子树的最左边节点,否则是向上链接节点的祖先节点

public class TreeLinkNode {

    int val;
    TreeLinkNode left = null;
    TreeLinkNode right = null;
    TreeLinkNode next = null;

    TreeLinkNode(int val) {
        this.val = val;
    }
}
  1.     class TreeLinkNode {
  2.         int val;
  3.         TreeLinkNode left = null;
  4.         TreeLinkNode right = null;
  5.         TreeLinkNode next = null;
  6.         TreeLinkNode(int val) {
  7.             this.val = val;
  8.         }
  9.     }
  10.     public TreeLinkNode getNext(TreeLinkNode tlnode){
  11.         if(tlnode.right != null){                       //如果一个节点的右子树不为空,那么该节点的下一个节点就是右子树的最左节点
  12.             TreeLinkNode node = tlnode.right;
  13.             while(node.left != null){
  14.                 node = node.left;
  15.             }
  16.             return node;
  17.         }else{                                             //否则,向上找第一个左链接指向的树所包含的祖先节点
  18.             while(tlnode.next != null){
  19.                 TreeLinkNode parent = tlnode.next;
  20.                 if(parent.left == tlnode)
  21.                     return parent;
  22.                 tlnode = tlnode.next;
  23.             }
  24.         }
  25.         
  26.         return null;
  27.     }

4 、用两个栈实现队列

题目描述

用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。

解题思路

1 )栈先进后出,队列是先进先出

2)用两个栈实现队列,其实就是完成先进先出操作,也就是,一个栈作为输入栈,使得数据“先进后出”,另一个栈作为输出栈,将输入站的数据输入到输出栈中,实现原来数据顺序的逆序进入,然后再输出即可

3)栈1,输入----》输出到栈2------》栈2输出,即可实现先进先出。注意判断是否为空栈

剑指offer代码:

  1. import java.util.Stack;
  2. public class Solution {
  3.            Stack<Integer> stack1 = new Stack<Integer>();
  4.        Stack<Integer> stack2 = new Stack<Integer>();
  5.        public void push(int node){
  6.            while(!stack2.isEmpty()){
  7.                stack1.push(stack2.pop());
  8.            }
  9.            stack2.push(node);
  10.        }
  11.        public int pop(){
  12.            while(!stack1.isEmpty()){
  13.               stack2.push(stack1.pop());
  14.            }
  15.            return  stack2.pop();
  16.        }
  17. }

本地代码:

  1. public class testStackArray {
  2.     /**
  3.      * @param ycy
  4.      */
  5.     Stack<Integer> stackIn = new Stack<Integer>();
  6.     Stack<Integer> stackOut = new Stack<Integer>();
  7.     public void push(int node){
  8.         stackIn.push(node);
  9.     }
  10.     public int pop(int node){
  11.         if(stackOut.isEmpty()){
  12.             while(!stackIn.isEmpty()){
  13.                 stackOut.push(stackIn.pop());
  14.             }
  15.         }
  16.         if(stackOut.isEmpty()){
  17.             return -111111;
  18.         }
  19.         return stackOut.pop();
  20.     }
  21. }

扫码关注一起随时随地学习!!!就在洋葱攻城狮,更多精彩,等你来!!

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洋葱ycy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值