go数据结构-线性表

线性表:顺序存储和链式存储

package dataStructure

import (
    "errors"
    "strconv"
)

const (
    CAPACITY = 20
)

type Book struct {
    ID   int
    Name string
}

// 线性表接口
type List interface {
    Get(index int) (obj interface{}, err error)
    Add(obj interface{}) (index int, err error)
    AddIndex(index int, obj interface{}) error
    Delete(index int) error
    Size() int
}

// 顺序存储-begin
// 顺序存储结构
type ArrayList struct {
    data   [CAPACITY]interface{}
    length int
}

// 获取元素,复杂度O(1)
func (list *ArrayList) Get(index int) (interface{}, error) {
    if index >= list.length || index < 0 {
        return nil, errors.New("index out of bound")
    }
    return list.data[index], nil
}

// 尾部插入元素,复杂度O(1)
func (list *ArrayList) Add(obj interface{}) (int, error) {
    if list.length == CAPACITY {
        return -1, errors.New("can not insert element, because the table is full")
    }
    index := list.length
    list.length++
    list.data[index] = obj
    return index, nil
}

// 指定下标插入元素,复杂度O(n)
func (list *ArrayList) AddIndex(index int, obj interface{}) error {
    if list.length == CAPACITY || index < 0 || index >= CAPACITY {
        return errors.New("table full or index out of bound!")
    }
    if index >= list.length {
        list.data[index] = obj
    } else {
        for i := list.length - 1; i >= index; i-- {
            list.data[i+1] = list.data[i]
        }
        list.data[index] = obj
    }
    list.length++
    return nil
}

// 删除指定下标,复杂度O(n)
func (list *ArrayList) Delete(index int) error {
    if index < 0 || index >= list.length {
        return errors.New("index out of bound!")
    }
    for i := index; i < list.length-1; i++ {
        list.data[i] = list.data[i+1]
    }
    list.length--
    return nil
}

func (list *ArrayList) Size() int {
    return list.length
}

// 顺序存储-end

// 链式存储-begin
type Node struct {
    data interface{}
    next *Node
    pre  *Node
}
type LinkedList struct {
    header  *Node
    current *Node
    tail    *Node
    length  int
}

func (node Node) hasNext() bool {
    if node.next == nil {
        return false
    }
    return true
}

// 获取元素,复杂度O(n)
func (list *LinkedList) Get(index int) (interface{}, error) {
    if index >= list.length || index < 0 {
        return nil, errors.New("index out of bound")
    }
    list.current = list.header
    i := 0
    for list.current.hasNext() {
        list.current = list.current.next
        if i == index {
            return list.current, nil
        }
        i++
    }
    return nil, errors.New("can not find index " + strconv.Itoa(index))
}

// 尾部插入元素,复杂度O(1)
func (list *LinkedList) Add(obj interface{}) (int, error) {
    if list.length == CAPACITY {
        return -1, errors.New("can not insert element, because the table is full")
    }
    index := list.length
    node := obj.(*Node)
    list.tail.next = node
    node.pre = list.tail
    list.tail = node
    list.length++
    return index, nil
}

// 指定下标插入元素,复杂度O(n)
func (list *LinkedList) AddIndex(index int, obj interface{}) error {
    if list.length == CAPACITY || index < 0 || index >= CAPACITY {
        return errors.New("table full or index out of bound!")
    }
    insertNode := obj.(*Node)
    if index >= list.length {
        list.tail.next = insertNode
    } else {
        node, err := list.Get(index)
        if err != nil {
            panic(err)
        }
        node.(*Node).next = insertNode
    }
    insertNode.pre = list.tail
    list.tail = insertNode
    list.length++
    return nil
}

// 删除指定下标,复杂度O(n)
func (list *LinkedList) Delete(index int) error {
    if index < 0 || index >= list.length {
        return errors.New("index out of bound!")
    }
    node, err := list.Get(index)
    if err != nil {
        panic(err)
    }
    current := node.(*Node)
    if index == list.length-1 {
        list.tail = current.pre
    } else {
        current.pre.next = current.next
    }
    current = nil
    list.length--
    return nil
}

func (list *LinkedList) Size() int {
    return list.length
}

// 链式存储-end
/*
func main() {
    var sqList List
    var books [CAPACITY]interface{}
    sqList = &ArrayList{books, 0}
    for i := 0; i < CAPACITY; i++ {
        index := i + 1
        _, e := sqList.Add(Book{index, "study in go " + strconv.Itoa(index)})
        if e != nil {
            panic(e)
        }
    }

    book, err := sqList.Get(2)
    if err != nil {
        panic(err)
    }
    
    fmt.Println(book.(Book))
}
*/
sosop hou 22 November 2015
blog comments powered by Disqus