Go数据结构之单链表(LinkedList)

时间:2022-02-26 10:18:14

单链表-LinkedList

    链表Linked list)是一种常见的基础数据结构,但是并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针。由于不必须按顺序存储,链表在插入的时候可以达到O(1),比顺序表快得多,但是查找一个节点或者访问特定编号的节点则需要O(n)的时间。

    以下是我用Go语言实现的单链表:

/**
 * Created with IntelliJ IDEA.
 * Date: 4/24/14
 * Time: 5:11 PM
 * 这是一个自定义的单链表数据结构.
 * Author: requelqi@gmail.com
 * Copyright 2014 Requelqi. All rights reserved.
 */
package LinkedList

import (
    "reflect"
    "fmt"
    "errors"
)

//链表中的数据类型
type ElementType interface {}

//节点结构体
type INode struct {
    X ElementType //节点
    next *INode   //下一节点指针
}

//链表结构体
type LinkedList struct {
    Head *INode //有一个头节点
}

func NewINode(x ElementType, next *INode) *INode {
    return &INode{x, next}
}
func NewLinkedList() *LinkedList {
    //头节点的数据域存储链表数据元素的大小(不包括头节点)
    head := &INode{0, nil}
    return &LinkedList{head}
}

/**
 * 判断链表是否为空
 */
func (list *LinkedList) IsEmpty() bool {
    return list.Head.next == nil
}

/**
 * 链表的长度
 */
func (list *LinkedList) Length() int {
    return int(reflect.ValueOf(list.Head.X).Int())
}

/**
    向链表后端Append元素
 */
func (list *LinkedList) Append(node *INode) {
    current := list.Head
    for {
        if current.next == nil {
            break
        }
        current = current.next
    }
    current.next = node
    list.sizeInc()
}

/**
    每次都在前端插入元素
 */
func (list *LinkedList) Prepend(node *INode) {
    current := list.Head
    node.next = current.next
    current.next = node
    list.sizeInc()
}

/**
    根据指定的数据查找*INode
 */
func (list *LinkedList) Find(x ElementType) (*INode, bool) {
    empty := list.IsEmpty()
    if empty {
        fmt.Println("This is an empty list")
        return nil, false
    }
    current := list.Head
    for current.next != nil {
        if current.X == x {
            return current, true
        }
        current = current.next
    }
    if current.X == x {
        return current, true
    }
    return nil, false
}
/**
    删除给定元素的节点
 */
func (list *LinkedList) Remove(x ElementType) error {
    empty := list.IsEmpty()
    if empty {
        return errors.New("This is an empty list")
    }
    current:=list.Head
    for current.next!=nil{
       if current.next.X==x{
          current.next=current.next.next
           list.sizeDec()
           return nil
       }
        current=current.next
    }
    return nil
}

/**
    内部函数,处理头节点记录的链表大小
 */
func (list *LinkedList) sizeInc() {
    v := int(reflect.ValueOf((*list.Head).X).Int())
    list.Head.X = v + 1
}
/**
    内部函数,处理头节点记录的链表大小
 */
func (list *LinkedList) sizeDec() {
    v := int(reflect.ValueOf((*list.Head).X).Int())
    list.Head.X = v - 1
}

/**
    打印链表信息
 */
func (list *LinkedList) PrintList() {
    empty := list.IsEmpty()
    if empty {
        fmt.Println("This is an empty list")
        return
    }
    current := list.Head.next
    fmt.Println("The elements is:")
    i := 0
    for ; ; i++ {
        if current.next == nil {
            break
        }
        fmt.Printf("INode%d ,value:%v -> ", i, current.X)
        current = current.next
    }
    fmt.Printf("Node%d value:%v", i + 1, current.X)
    return

}

  done~