最简单上手Go语言常用数据结构与算法代码, 你可以通过这篇文章来学习如何构建栈与队列,来应用于实际算法问题中。
栈和队列都是数据结构中的基本操作,它们分别对应着“后进先出”(LIFO)和“先进先出”(FIFO)的操作特点,它们的优缺点及使用场景如下:
栈的优点:
- 栈的操作非常简单,只需要对栈顶进行操作,效率较高。
- 栈可以非常方便地实现递归操作。
- 栈可以用于判断括号匹配、表达式求值、深度优先搜索等场景。
栈的缺点:
- 栈的存储空间是固定的,可能会发生栈满的情况。
- 栈只支持在一端进行插入和删除操作。
队列的优点:
- 队列可以实现数据的先进先出,保证了数据的有序性。
- 队列的插入和删除操作都在不同的端进行,避免了栈可能会发生的栈满的情况。
- 队列可以用于广度优先搜索、循环队列等场景。
队列的缺点:
- 队列的出队操作比较耗时,因为每次出队都要将队列中的元素前移一位。
- 队列只支持在队列头和队列尾进行插入和删除操作,不能在队列中间进行操作。
综上所述,栈和队列在实际应用中都有各自的优点和缺点,需要根据实际情况进行选择。一般来说,如果需要实现递归或者括号匹配等场景,可以使用栈;如果需要保证数据的先进先出或者实现广度优先搜索等场景,可以使用队列。
1. 栈
package main
import "fmt"
// 定义栈结构体
type Stack struct {
data []interface{} // 用切片来存储栈中的数据
}
// 初始化栈
func (s *Stack) Init() {
s.data = []interface{}{}
}
// 判断栈是否为空
func (s *Stack) IsEmpty() bool {
return len(s.data) == 0
}
// 获取栈顶元素
func (s *Stack) Peek() interface{} {
if s.IsEmpty() {
return nil
}
return s.data[len(s.data)-1]
}
// 入栈操作
func (s *Stack) Push(value interface{}) {
s.data = append(s.data, value)
}
// 出栈操作
func (s *Stack) Pop() interface{} {
if s.IsEmpty() {
return nil
}
lastIndex := len(s.data) - 1
value := s.data[lastIndex]
s.data = s.data[:lastIndex]
return value
}
func main() {
// 创建一个栈并进行操作
stack := Stack{}
stack.Init()
// 入栈操作
stack.Push(1)
stack.Push(2)
stack.Push(3)
// 出栈操作
fmt.Println(stack.Pop()) // 3
fmt.Println(stack.Pop()) // 2
// 获取栈顶元素
fmt.Println(stack.Peek()) // 1
// 判断栈是否为空
fmt.Println(stack.IsEmpty()) // false
// 清空栈
stack.Init()
fmt.Println(stack.IsEmpty()) // true
}
上面的代码定义了一个Stack
结构体,包括了栈的常用操作:初始化、判断栈是否为空、获取栈顶元素、入栈、出栈。其中,栈的数据使用切片进行存储。在main
函数中,创建一个栈并进行操作,最后清空栈。
2. 队列
package main
import "fmt"
// 定义队列结构体
type Queue struct {
data []interface{} // 用切片来存储队列中的数据
}
// 初始化队列
func (q *Queue) Init() {
q.data = []interface{}{}
}
// 判断队列是否为空
func (q *Queue) IsEmpty() bool {
return len(q.data) == 0
}
// 获取队首元素
func (q *Queue) Peek() interface{} {
if q.IsEmpty() {
return nil
}
return q.data[0]
}
// 入队操作
func (q *Queue) Enqueue(value interface{}) {
q.data = append(q.data, value)
}
// 出队操作
func (q *Queue) Dequeue() interface{} {
if q.IsEmpty() {
return nil
}
value := q.data[0]
q.data = q.data[1:]
return value
}
func main() {
// 创建一个队列并进行操作
queue := Queue{}
queue.Init()
// 入队操作
queue.Enqueue(1)
queue.Enqueue(2)
queue.Enqueue(3)
// 出队操作
fmt.Println(queue.Dequeue()) // 1
fmt.Println(queue.Dequeue()) // 2
// 获取队首元素
fmt.Println(queue.Peek()) // 3
// 判断队列是否为空
fmt.Println(queue.IsEmpty()) // false
// 清空队列
queue.Init()
fmt.Println(queue.IsEmpty()) // true
}
上面的代码定义了一个Queue
结构体,包括了队列的常用操作:初始化、判断队列是否为空、获取队首元素、入队、出队。其中,队列的数据使用切片进行存储。在main
函数中,创建一个队列并进行操作,最后清空队列。