一、什么是队列?
队列是一种特殊的线性表,只能在队列的尾部添加元素,在队列的头部删除元素,先进先出(FIFO)
二、代码实现
type Queue interface {
Offer(e interface{}) /*队列尾部插入元素*/
Poll() interface{} /*删除并返回队列前端元素*/
Peek() interface{} /*返回队列前端元素*/
Clear() /*清空队列*/
Size() int /*队列长度*/
IsEmpty() bool /*判断队列是否为空*/
Print()/*打印队列元素*/
}
/*通过数组实现队列*/
type ArrayList struct {
e []interface{}
}
/*初始化-*/
func NewArryList() *ArrayList {
return &ArrayList{}
}
func (queue *ArrayList) Offer(e interface{}) {
queue.e = append(queue.e,e)
}
func (queue *ArrayList) Poll() interface{} {
if queue.IsEmpty() {
fmt.Println("queue is empty")
return nil
}
firstE := queue.e[0]
queue.e = queue.e[1:]
return firstE
}
func (queue *ArrayList) Peek() interface{} {
if queue.IsEmpty() {
fmt.Println("queue is empty")
return nil
}
return queue.e[0]
}
func (queue *ArrayList) IsEmpty() bool {
return len(queue.e) == 0
}
func (queue *ArrayList) Size() int {
return len(queue.e)
}
func (queue *ArrayList) Clear() {
if queue.IsEmpty() {
return
}
for i := 0 ; i< len(queue.e) ; i++ {
queue.e[i] = nil
}
queue.e = nil
}
func (queue *ArrayList) Print() {
if queue.IsEmpty() {
return
}
for i := 0 ; i< len(queue.e) ; i++ {
fmt.Print(queue.e[i]," ")
}
fmt.Println()
}
type LinkedList struct{
e interface{}
next *LinkedList /*下一个节点*/
previous *LinkedList /*上一个节点*/
size int
last *LinkedList /*最后一个节点*/
}
/*初始化*/
func NewLinkedList() *LinkedList {
return &LinkedList{}
}
func (node *LinkedList) Offer(e interface{}) {
node.size += 1
if node.e == nil {
node.e = e
node.last = node
return
}
newNode := &LinkedList{
e: e,
next: nil,
previous: node.last,
size: node.size,
last: nil,
}
node.last.next = newNode
node.last = newNode
}
func (node *LinkedList) Poll() interface{} {
if node.IsEmpty() {
return nil
}
firstE := node.e
if node.next != nil {
lastNode := node.last
node.next.size = node.size -1
node.next.previous = nil
*node = *node.next
if node.size == 1 {
/*只有两个节点,移除头节点,剩下一个节点,指针指向第二个节点,最后一个结点,也就是头节点本身*/
node.last = node
}else {
node.last = lastNode
}
}else {
var nilNode LinkedList
*node = nilNode
}
return firstE
}
func (node *LinkedList) Peek() interface{} {
return node.e
}
func (node *LinkedList) Clear() {
/*gc采用三色标记算法,传统标记清楚算法,指针指向nil,等待gc回收*/
var nilNode LinkedList
p := node
for p != nil {
temp := p
p.e = nil
p.previous = nil
p = p.next
*temp = nilNode
}
*node = nilNode
}
func (node *LinkedList) Size() int {
return node.size
}
func (node *LinkedList) IsEmpty() bool {
return node.size == 0
}
func (node *LinkedList) Print() {
p := node
for p != nil {
fmt.Print(p.e," ")
p = p.next
}
fmt.Println()
}
三、数组实现和链表实现的对比
3.1 数组实现
优点:数据结构简单,在内存中连续存贮,占用字节少,遍历比较快
缺点:每次添加和删除元素改变数组长度,都要构建新的数组,开销比较大
3.2 链表实现
优点:数据结构复杂,占用字节数相比数组结构较多,添加和删除简单方便,只用移动指针就好
缺点:遍历比较慢,应为要通过指针去寻址,指针对象也要占用一定的内存空间
ps: 有不正确的地方欢迎指出