Go-单链表-栈和队列

package main

import (
	"errors"
	"fmt"
	"log"
)

// 单链表
// 特征:
//		1. 每个节点都包含指向下一个节点的指针 next
//		2. 链表逻辑上是序列,但在内存中存储是不规则的
// 实现:
//		1. 头节点(根节点) head 单链表的起始位置,头节点不存放任何数据
//		2. 链表用来实现队列、栈、有序序列(插入排序)
//		3. 链表方法:
//			a. 添加一个节点 Add
//			b. 移除一个节点
//			c. 遍历节点

// ValNode 值节点,存放所需数据,至于数据是什么,已经不重要,重要的是有一个指向下一个值节点的指针 next
type ValNode struct {
	// data 存放数据
	data interface{}
	// 指向下一个节点的值节点指针,如果没有则为空地址 nil
	next *ValNode
}

// SingleLink 单链表,包含一个指向链表头部的指针 head
type SingleLink struct {
	// 头指针 head 指向链表的头部
	head *ValNode
}

func NewSingleLink() *SingleLink {
	return &SingleLink{
		head: &ValNode{},
	}
}

// AddNode 在尾部添加一个节点: 找打尾部节点,将尾部节点的next指向新增加的节点
func (sl *SingleLink) AppendNode(v *ValNode)  {
	// 1. 找到尾部
	tmp := sl.head
	for tmp.next != nil {
		tmp = tmp.next
	}
	// 2. 在尾部添加一个节点
	tmp.next =  v
}

// 在尾部删除一个节点: 判断链表是否为空,判断链表是否只有一个元素,找到链表最后的上一个元素将next置为nil
func (sl *SingleLink) PopNode() (v *ValNode, err error) {
	// 1. 判断是否是空链表, 空链表则返回空链表错误
	if sl.head.next == nil {
		err = errors.New("链表为空")
		return
	}

	// 2. 判断链表是否只有一个元素,如果为一个元素则将 head头节点的next置为 nil
	if sl.head.next.next == nil {
		v = sl.head.next
		sl.head.next = nil
	}
	// 3. 找到链表的上一个元素将next置为nil
	tmp := sl.head
	for tmp.next.next != nil {
		tmp = tmp.next
	}
	v = tmp.next
	tmp.next = nil
	return
}

// 在头部删除一个节点: 判断链表是否为空,判断链表是否只有一个元素,将链表头指向链表头指向的下一个元素
func (sl *SingleLink) PopLeftNode() (v *ValNode, err error) {
	// 1. 判断是否是空链表, 空链表则返回空链表错误
	if sl.head.next == nil {
		err = errors.New("链表为空")
		return
	}

	// 2. 判断链表是否只有一个元素,如果为一个元素则将 head头节点的next置为 nil
	if sl.head.next.next == nil {
		v = sl.head.next
		sl.head.next = nil
	}
	// 3. 获取链表头指向的下一个元素,并将链表头指向的下一个元素的下一个元素
	v = sl.head.next
	sl.head.next = sl.head.next.next
	return
}

// ListLink 遍历列表,判断链表是否为空
func (sl *SingleLink) ListLink() {
	// 1. 判断是否是空链表
	if sl.head.next == nil {
		fmt.Println("SingleLink empty")
		return
	}
	// 2. 遍历链表
	tmp := sl.head.next
	for tmp != nil {
		fmt.Println(tmp.data)
		tmp = tmp.next
	}
}

// 通过链表的 AppendNode 和 PopNode实现了栈
// 通过链表的 AppendNode 和 PopLeftNode实现了队列

func main() {
	sl := NewSingleLink()
	node1 := &ValNode{
		data: 100,
	}
	node2 := &ValNode{
		data: 200,
	}
	sl.AppendNode(node1)
	sl.AppendNode(node2)
	node3, err := sl.PopNode()
	if err != nil {
		log.Println(err)
	}
	fmt.Println(node3)
	sl.ListLink()
}

  

原文地址:https://www.cnblogs.com/2bjiujiu/p/14428653.html