zoukankan      html  css  js  c++  java
  • Golang单链表反转(迭代与栈方式)

    代码如下(代码大意表达,没有考虑和处理各种空等意外情况):

    package main
    
    import (
    	"strings"
    
    	"github.com/golang-collections/collections/stack"
    )
    
    type node struct {
    	i    int
    	next *node
    }
    
    var linkList *node
    
    func makeList() {
    	// 创建一个单链表: 0->1->2->3->4->5->6->7->8->9
    	// 这里依次遍历到尾部追加,也可以使用一个尾指针来指示快速添加
    	linkList = &node{i: 0}
    	for i := 1; i < 10; i++ {
    		linkList := linkList
    		for {
    			if linkList.next == nil {
    				linkList.next = &node{i: i}
    				break
    			}
    			linkList = linkList.next
    		}
    	}
    }
    
    func traverse() {
    	// 遍历单链表
    	iter := linkList
    	for {
    		if iter != nil {
    			if iter.next == nil {
    				print(iter.i)
    			} else {
    				print(iter.i, "->")
    			}
    			iter = iter.next
    		} else {
    			break
    		}
    	}
    	println()
    }
    
    func reverse() {
    	// 迭代反转链表
    
    	var next *node // 反转后所应该指向的下一个节点,默认初始化为空
    	for {
    		// 首先保存原链表反转前的下一个节点
    		tmp := linkList.next
    
    		// 反转后所应该指向的下一个节点
    		linkList.next = next
    		// 上面两步对于一个节点来说先保存其旧next,然后用新next覆盖
    
    		// 当前节点已反转,它应当被下一个待反转节点next指向,这里把它覆盖存入next中
    		next = linkList
    
    		// tmp来自每个节点的next,如果tmp为空,说明已经反转到最后一个节点了
    		if tmp == nil {
    			break
    		} else {
    			// tmp不为空,将当前节点指针linkList推进到下一个节点,即推进到tmp(反转工作循环前两步已经完成)
    			linkList = tmp
    		}
    	}
    }
    
    func reverseByStack() {
    	// 初始化一个栈
    	s := stack.New()
    	for {
    		if linkList != nil {
    			// 每个节点依次压栈
    			s.Push(linkList)
    			linkList = linkList.next
    		} else {
    			break
    		}
    	}
    
    	// 弹栈,获取最后一个栈元素
    	iter := s.Pop().(*node)
    
    	// 保存最后一个元素(反正后第一个元素)指针
    	linkList = iter
    
    	for {
    		// 栈不空时,说明所有节点未处理完
    		if s.Len() > 0 {
    			// 依次出栈
    			iter.next = s.Pop().(*node)
    
    			// 上一个出栈节点指向当前出栈节点
    			iter = iter.next
    		} else {
    			break
    		}
    	}
    	iter.next = nil
    }
    
    func m() {
    	makeList()
    	traverse()
    
    	reverse()
    	traverse()
    
    	reverse()
    	traverse()
    
    	reverse()
    	traverse()
    }
    
    func n() {
    	makeList()
    	traverse()
    
    	reverseByStack()
    	traverse()
    
    	reverseByStack()
    	traverse()
    
    	reverseByStack()
    	traverse()
    }
    
    func main() {
    	m()
    	println(strings.Repeat("=", 28))
    	n()
    }
    

      

    对于栈方式反转示意图如下

    程序运行结果:

  • 相关阅读:
    NOIP模拟 10
    无聊的 邮递员 插头dp
    类实例化对象可以访问静态(static)方法,但是不能访问静态属性。
    PHP——抽象类与接口的区别
    工厂模式
    win10 专业版 git bash 闪退问题终极解决方案
    git基本的使用原理
    排序算法-插入排序
    如何进行CodeReview
    php中的各种http报错的报错的状态码的分析
  • 原文地址:https://www.cnblogs.com/pluse/p/13055190.html
Copyright © 2011-2022 走看看