最近在看Go开源项目源码时越发感觉基础知识点重要性。。。好吧,就拿数据结构和算法开始补。。。

package main

import "fmt"

// 双向链表

// 元素属性
type Element interface {}

// 节点数据结构
type DoubleNode struct {
	Data interface{}
	Next *DoubleNode
	Prev *DoubleNode
}

////////////////////////////////////////////////节点操作
// 创建节点
func NewNode(data Element) *DoubleNode {
	return &DoubleNode{
		Data: data,
		Next: nil,
		Prev: nil,
	}
}

// 获取前节点
func (d *DoubleNode) prev() *DoubleNode {
	return d.Prev
}

// 获取后节点
func (d *DoubleNode) next() *DoubleNode {
	return d.Next
}

///////////////////////////////////////////// 双向链表操作
// 链表数据结构
type List struct {
	// 链表头节点
	head *DoubleNode
	// 链表尾节点
	tail *DoubleNode
	// 链表长度
	len int
}

func NewListNode() *List {
	return &List{head:nil, tail:nil, len:0}
}

// 返回链表头节点
func (l *List) Head() *DoubleNode {
	return l.head
}

// 返回链表尾节点
func (l *List) Tail() *DoubleNode {
	return l.tail
}

// 返回链表长度
func (l *List) Len() int {
	return l.len
}

// 链表右侧插入元素
func (l *List) RPush(data Element) {
	node := NewNode(data)

	if l.Len() == 0 {
		// 初始化头结点和尾节点
		l.head = node
		l.tail = node
	} else {
		// 读取出慢一步的指针作为老数据
		old := l.tail
		// 将老数据放入放入到左节点(上一节点)
		node.Prev = old
		// 当前新输入放入有节点(下一节点)
		l.tail.Next = node
		l.tail = node
	}

	l.len++
}

func (l *List) Lpop() (node *DoubleNode) {
	if l.Len() == 0 {
		return
	}

	// 从尾部开始走
	node = l.head
	if node.Next == nil {
		l.head = nil
		l.tail = nil
	} else {
		// 取尾部 上一节点
		l.head = node.Next
	}

	l.len--
	return
}

func (l *List) Index() {
}

func (l *List) Trans() {
	h := l.tail

	for h != nil {
		fmt.Printf("h:%d \n",h.Data)
		h = h.Prev
	}
}


func main() {
	nn := NewListNode()
	nn.RPush(111)
	nn.RPush(222)
	nn.RPush(333)
	nn.RPush(444)
	//nn.Index()

	fmt.Println(nn.Lpop().Data)
	fmt.Println(nn.Len())
	fmt.Println(nn.Lpop().Data)
	fmt.Println(nn.Len())
	fmt.Println(nn.Lpop().Data)
	fmt.Println(nn.Len())
	fmt.Println(nn.Lpop().Data)
	//nn.Trans()
}