数据结构和算法_数组/链表反转

来源:互联网 发布:云豹直播源码破解版 编辑:程序博客网 时间:2024/05/18 01:04

问题:如何在不新增数组或者链表的基础上,将原数组、链表反转

1.数组反转:

<思路>通过两个位移指针l和r,l指向数组的第一个元素,r指向最后一个元素,然后在同一个循环中引入temp变量交换l指针和r指针对应的数据,交换完成以后同时向中间移动一步(l++,r--)一直到相遇为止。这里这个循环的条件是左指针小于右指针

<代码>

package 数组和链表;public class ReverseArray {public static void main(String[] args){ReverseArray demo = new ReverseArray();int[] mylist = {5,89,67,918,3,46,768,12};System.out.println("原数组:");demo.printOut(mylist);  //打印原数组demo.reverseList(mylist);System.out.println("\n反转后的数组:");demo.printOut(mylist);  //打印反转后的数组}//打印数组的函数private void printOut(int[] list){int len = list.length;for(int i = 0;i<len;i++){System.out.print(list[i]+"\t");}}//反转函数public void reverseList(int[] list){int len = list.length;int l = 0;int r = len-1;  //右指针int temp = 0;    //交换左右指针的时候引入的临时变量//注意这里的判断交换停止的条件,数组长度的奇偶也要考虑while(l < r){temp = list[r];list[r] = list[l];list[l] = temp;l++;r--;}}}


链表反转

<思路>采用递归算法,为甚么想到用递归算法,因为给你一个链表的头部,要我们反转,就必须从链表的最后一个开始操作,也就是说要先从头节点向下找到尾节点,然后再从尾节点逐层操作返回到头结点,这种自顶向下,从大到小,然后从小或者下反弹向上操作的过程就是递归的过程,所以采用递归的方法。算法里面我们要做哪些事?1.递归的底部在哪里,反弹条件是什么。2.在递归到底部的时候,需要返回么,要返回的话返回什么。3. 递归反弹以后的操作是什么。这里主要操作就是建立相邻的两个节点之间的新关系,让后一个节点指向前一个,前一个节点指向null。

<代码>

package 数组和链表;import java.util.Random;//节点定义public class ReverseLink {class Node{Node next = null;int number =0;}//链表的节点里面的值采用随机数产生private Random random = new Random(System.currentTimeMillis());public static void main(String[] args){ReverseLink demo = new ReverseLink();//创建链表Node head = demo.createLink(6);//打印创建完的链表System.out.println("原始链表是:");demo.printLink(head);//反转链表Node nHead = demo.reverseLink_recursive(head);//打印反转后的链表System.out.println("\n反转后的链表:");demo.printLink(nHead);}//递归法,反转链表,返回新的链表头private Node reverseLink_recursive(Node head){   //函数需要返回头节点if(head == null || head.next == null) //反弹条件是当前节点为空(防止一开始就传入空链表)或者当前节点的next指向null(最后一个节点)return head;  //返回原来链表的尾节点作为新链表的头节点else{/** * 这个部分是递归的核心,递归算法的核心是两个问题: * 1.分下去的时候,是在重复哪个过程(操作)?这里是不断让当前节点产生下一次递归所需要的参数——子链表的头节点 * 2.合上来的时候,需要在谁之间重新建立怎样的关系?这里的是在相邻的两个节点之间,让后者的next指针指向前者,前者的next指针指向null *///分的过程Node second_node = head.next; Node nHead = reverseLink_recursive(second_node);//合的过程second_node.next = head;head.next = null;return nHead;}}//创建链表,返回链表头private Node createLink(int len){/** * 1.创建链表关键是使用了head头节点指针和tail尾节点指针 * 2.新增节点的过程就是不断让原链表tail节点的next指向新节点,然后tail指针指向新节点的过程 * 3.这样创建的链表的head其实不是真的head,这个head的weight往往用来表示链表的长度 */Node head = new Node();Node tail = head;head.number = len;for(int i =0;i<len;i++){Node node = new Node();node.number = random.nextInt(100);tail.next = node;tail = node;}return head;}//输出打印链表private void printLink(Node head){Node temp = head;while(temp != null){System.out.print(temp.number+"\t");temp = temp.next;}return;}}