package main

//链表节点
type doublLinkeNode struct {
	data interface{}     //节点存在的数据
	pre  *doublLinkeNode //指向上一个节点的指针
	next *doublLinkeNode //指向下一个节点的指针
}

//链表数据结构(两个指针 一个指向头节点、一个指向尾节点 便于可以从两边获取数据)
type doubleLink struct {
	head   *doublLinkeNode //指向头结点
	tail   *doublLinkeNode //指向尾节点
	length int64           //链表长度
}

//初始化链表
func initDoubleLink() (dl *doubleLink) {
	dl = &doubleLink{}
	dl.head = nil
	dl.tail = nil
	dl.length = 0
	return
}

//往链表的头部添加节点
func (this *doubleLink) addLNode(data interface{}) int64 {
	newNode := &doublLinkeNode{data: data}
	if this.length == 0 {
		this.head = newNode
		this.tail = newNode
	} else {
		head := this.head
		newNode.next = head
		head.pre = newNode
		this.head = newNode
	}
	this.length++
	return this.length
}

//往链表尾部添加节点
func (this *doubleLink) addRNode(data interface{}) int64 {
	newNode := &doublLinkeNode{data: data}
	if this.length == 0 {
		this.head = newNode
		this.tail = newNode

	} else {
		tail := this.tail //获取当前链表的尾节点
		tail.next = newNode
		newNode.pre = tail
		this.tail = newNode
	}
	this.length++
	return this.length
}

//遍历链表
func (this *doubleLink) rangeLink() []interface{} {
	if this.length == 0 {
		return nil
	}
	var list []interface{}
	node := this.head
	for {
		list = append(list, node.data)
		if node.next == nil {
			break
		} else {
			node = node.next
		}
	}
	return list
}

//获取某个位置的节点
func (this *doubleLink) getValue(index int64) interface{} {
	if this.length == 0 {
		return nil
	}
	node := this.head
	var count int64
	for {
		if count == index {
			return node.data
		}
		if node.next == nil {
			break
		}
		node = node.next
		count++
	}
	return nil
}

func main() {
	doubleLink := initDoubleLink()
	doubleLink.addRNode(123)
	doubleLink.addRNode(789)
	doubleLink.addRNode(338)
	doubleLink.addLNode(996)
	doubleLink.addRNode(789)
	doubleLink.addRNode("this is string")
	values := doubleLink.rangeLink()
	for _, v := range values {
		fmt.Println("node value:", v)
	}
	var index int64
	index = 1
	fmt.Println("index:", index, " value:", doubleLink.getValue(index))
}