集合总结之单链表反转

概念简述

       单链表是一种链式存取的数据结构,用一组地址任意的存储单元存放线性表中的数据元素。链表中的数据是以结点来表示的,每个结点的构成:元素(数据元素的映象) + 指针(指示后继元素存储位置),元素就是存储数据的存储单元,指针就是连接每个结点的地址数据。

结点数据结构

┌───┬───┐

│data │next │

└───┴───┘

  • data域--存放结点值的数据域
  • next域--存放结点的直接后继的地址(位置)的指针域(链域)

       链表通过每个结点的链域将线性表的n个结点按其逻辑顺序链接在一起的,每个结点只有一个链域的链表称为单链表(Single Linked List)。单链表中每个结点的存储地址是存放在其前趋结点next域中,而开始结点无前趋,故应设头指针head指向开始结点。链表由头指针唯一确定,单链表可以用头指针的名字来命名。
终端结点无后继,故终端结点的指针域为空,即NULL。

存储方法

链接方式存储的线性表简称为链表(Linked List),链表的具体存储表示为:

① 用一组任意的存储单元来存放线性表的结点(这组存储单元既可以是连续的,也可以是不连续的);

② 链表中结点的逻辑次序和物理次序不一定相同。为了能正确表示结点间的逻辑关系,在存储每个结点值的同时,还必须存储指示其后继结点的地址(或位置)信息(称为指针(pointer)或链(link))
链式存储是最常用的存储方式之一,它不仅可用来表示线性表,而且可用来表示各种非线性的数据结构;

单链表反转示例

1.实体定义

/**
 * @author LGH
 * @date 2020/11/18 13:54
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TestNode {

    /**
     * 数据域
     */
    private Integer data;
    /**
     * 指针域
     */
    private TestNode next;

    public TestNode(Integer data) {
        this.data = data;
    }
}

2.生成链表

/**
 * @author LGH
 * @date 2020/11/18 13:58
 */
@Data
public class BuildChain {

    private  TestNode head;

    public BuildChain(int size) {
        TestNode head = new TestNode(0);
        TestNode cur = head;
        for (int i = 1; i < size; i++) {
            TestNode tmp = new TestNode(i);
            cur.setNext(tmp);
            cur = tmp;
        }
        this.head = head;
    }

    public static void main(String[] args) {
        TestNode head = new BuildChain(10).getHead();
        StringBuilder sb = new StringBuilder();
        TestNode cur = head;
        sb.append(cur.getData());
        while (null != cur.getNext()) {
            sb.append(" -> ");
            sb.append(cur.getNext().getData());
            cur = cur.getNext();
        }
        System.out.println(sb.toString());
    }
}

3.反转链表方式

    /**
     * 方法1 递归实现 当栈深度大于12000 则会出现StakOverflowError
     * 
     * @param head
     * @return
     */
    public static TestNode reverse1(TestNode head) {
        if (null == head || null == head.getNext())
            return head;
        TestNode revHead = reverse1(head.getNext());
        head.getNext().setNext(head);
        head.setNext(null);
        return revHead;
    }
	/**
	 * 以上即是递归实现的源码,但是需要考虑的问题是递归都在java栈中进行,
     *需要考虑jdk支持的栈的深度。在jdk1.8.0_91版本中,
     *当上述链表长度大于12000则会出现StackOverFlowError错误。
     *说明对于该版本jdk栈的深度不能大于12000。
	 *
	 /


    /**
     * 方法2 遍历实现 通用实现方法最好的方法是采用遍历的方式进行反转
     * 
     * @param head
     * @return
     */
     public static TestNode converseChain(TestNode node){
        if (null == node){
            return null;
        }

        TestNode preNode = node;
        TestNode currentNode = node.getNext();
        while (null != currentNode.getNext()){
            TestNode tempNode = currentNode.getNext();
            currentNode.setNext(preNode);
            preNode = currentNode;
            currentNode = tempNode;
        }
        currentNode.setNext(preNode);
        node.setNext(null);
        return currentNode;
    }



    /**
     * 方法3 利用其他数据结构 stack 考虑到stack具有先进后出这一特性,因此可以借助于stack数据结构来实现单向链表的反转。
     * @param head
     * @return
     */
    public static TestNode reverse3(TestNode head) {
        Stack<TestNode> stack = new Stack<TestNode>();
        for (TestNode node = head; null != node; node = node.getNext()) {
            stack.add(node);
        }
        TestNode reHead = stack.pop();
        TestNode cur = reHead;
        while(!stack.isEmpty()){
            cur.setNext(stack.pop());
            cur = cur.getNext();
            cur.setNext(null);
        }
        return reHead;
    }

如有披露或问题欢迎留言或者入群探讨

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
提供的源码资源涵盖了Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 适合毕业设计、课程设计作业。这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。 所有源码均经过严格测试,可以直接运行,可以放心下载使用。有任何使用问题欢迎随时与博主沟通,第一时间进行解答!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值