数据结构之Go实现线性表


线性表基础知识


线性表的基本概念

(1)线性表的定义

线性表是具有相同特性数据元素的一个有限序列。该序列中所含元素的个数叫作线性表的长度,用 n(n>0) 表示,n 可以等于零,表示线性表是一个空表。

(2) 线性表的逻辑特性

线性表只有一个表头元素,只有一个表尾元素,表头元素没有前驱,表尾元素没有后继,除表头和表尾元素之外,其他元素只有一个直接前驱,也只有一个直接后继。

(3)线性表的存储结构

线性表的存储结构有顺序存储结构链式存储结构两种。前者称为顺序表,后者称为链表。

  • 顺序表

顺序表就是把线性表中的所有元素按照其逻辑顺序,依次存储到从指定的存储位置开始的一块连续的存储空间中。
线性表中第一个元素的存储位置就是指定的存储位置,第i+1个元素的存储位置紧接在第i个元素的存储位置的后面。

  • 链表

在链表存储中,每个结点不仅包含所存元素的信息,还包含元素之间逻辑关系的信息,如单链表中前驱结点包含了后继结点的地址信息,这样就可以通过前驱结点中的地址信息找到后继结点的位置。

链表有以下 5 种形式:

  • 单链表

在每个结点中除了包含数据域外,还包含一个指针域,用以指向其后继结点。

① 带头结点的单链表中,头指针 head 指向头结点,头结点的值域不含任何信息,从头结点的后继结点开始存储数据信息。头指针 head != nil ,当 head.next == nil 时,链表为空。

② 不带头结点的单链表中的头指针 head 直接指向开始结点,即当 head == nil 时,链表为空。

两者最明显的区别:带头结点的单链表中有一个结点不存储信息(仅存储一些描述链表属性的信息,如表长),只是作为标志,而不带头结点的单链表的所有结点都存储信息。

  • 双链表

单链表只能由开始结点走到终端结点,而不能由终端结点反向走到开始结点。双链表在单链表结点上增添了一个指针域,指向当前结点的前驱。这样就可以方便地由其后继来找到其前驱,从而实现输出从终端结点到开始结点的数据序列。

双链表也分为带头结点的双链表和不带头结点的双链表,情况类似于单链表。

① 带头结点的双链表,当 head.Next == nil 时,链表为空;

② 不带头结点的双链表,当 head == nil 时,链表为空。

  • 循环单链表

循环单链表只要将单链表的最后一个指针域(空指针)指向链表中的第一个结点即可(这里之所以说第一个结点而不说是头结点是因为:如果循环单链表是带头结点的,则最后一个结点的指针域要指向头结点;如果循环单链表不带头结点,则最后一个指针域要指向开始结点)。

循环单链表可以实现从任一个结点出发访问链表中的任何结点,而单链表从任一结点出发后只能访问这个结点本身及其后边的所有结点。

① 带头结点的循环单链表,当 head == head.Next 时,链表为空;

② 不带头结点的循环单链表,当 head == nil 时,链表为空。

  • 循环双链表

循环双链表的构造源自双链表,即将终端结点的 Next 指针 指向链表中的第一个结点,将链表中第一个结点的 Prior 指针 指向终端结点。

循环双链表同样有带头结点和不带头结点之分。

① 当 head == nil 时,不带头结点的循环双链表为空。

② 带头结点的循环双链表中是没有空指针的,其空状态下,head.Nexthead.Prior 必然都等于 head 。所以判断其是否为空,只需要检查 这两个指针中的任意一个是否等于 head 指针 即可。因此,以下四句代码中的任意一句为真,都可以判断循环双链表为空。

head.Next == head
head.Prior == head
head.Next == head && head.Prior == head
head.Next == head || head.Prior == head
  • 静态链表

静态链表借助一维数组来表示,一般链表结点空间来自于整个内存,静态链表则来自于一个结构体数组。数组中的每一个结点含有两个分量:一个是数据元素分量 data ;另一个是指针分量,指示了当前结点的直接后继结点在数组中的位置。

静态链表中的指针不是通常所说的 C 语言中用来存储内存地址的指针型变量,而是一个存储数组下标的整型变量,通过它可以找到后继结点在数组中的位置,其功能类似于真实的指针,因此称其为指针。


线性表的结构体定义

(1)顺序表的结构体

// Array
type SeqList struct {
		Data [MaxSize]interface{} // MaxSize
		Length int
}

// Slice
type SliceList struct {
		Data []interface{}
		Length int
}

(2)单链表的结构体

type LinkedListNode struct {	
		Data interface{}
		Next *LinkedListNode
}

type LinkedList struct {
		Head *LinkedListNode
		Length int
}

(3) 双链表结点的结构体

type LinkedListNode struct {
		Data interface{}
		Next *LinkedLIstNode
}

type LinkedList struct {
		Head *LinkedListNode
		Length int
}

结点是内存中一片由用户分配的存储空间,只有一个地址来表示它的存在,没有显式的名称,因此在分配链表结点空间时定义一个指针来存储这片空间的地址(这个过程通俗地讲叫指针指向结点),并且常用这个指针的名称来作为结点的名称。


线性表的实现


数组顺序表

(1)数组顺序表的基本操作

type Operate interface {
        CreateList(n int, arr [5]int) error
        // 初始化顺序表
        InitList()	
        // 判断顺序表是否为空表
        IsEmpty() bool	
        // 返回顺序表的元素个数
        Len() int
        // 输出顺序表
        DisplayList()
        //  获取顺序表的第 i 个元素 e
        GetElem(i int) (e interface{})
        // 查找顺序表的元素 e
        LocalElem(e interface{}) (i int)
        // 在顺序表中的第 i 个位置上插入元素 e
        Insert(i int, e interface{})
        // 从顺序表中删除第 i 个元素 e
        Delete(i int) (e interface{})
}

(2)完整的程序代码

package main

import (
        "errors"
        "fmt"
)

const MaxSize = 20

type SeqList struct {
        Data   [MaxSize]interface{}
        Length int
}

func NewSeqList() *SeqList {
        return new(SeqList)
}

type Operate interface {
        CreateList(n int, arr [5]int) error
        InitList()
        Len() int
        IsEmpty() bool
        DisplayList()
        GetElem(i int) (e interface{})
        LocalElem(e interface{}) (i int)
        Insert(i int, e interface{})
        Delete(i int) (e interface{})
}

func (l *SeqList) CreateList(n int, arr [5]int) error {
        if n <= 0 || n > MaxSize {
                return errors.New("No Create the list!\n")
        } else {
                for i := 0; i < n; i++ {
                        l.Data[i] = arr[i]
                }
                l.Length = n
                return nil
        }
}

func (l *SeqList) InitList() {
        l.Length = 0
}

func (l *SeqList) Len() int {
        return l.Length
}

func (l *SeqList) IsEmpty() bool {
        return l.Length == 0
}

func (l *SeqList) DisplayList() {
        for i := 0; i < l.Length; i++ {
                fmt.Printf("%d ", l.Data[i])
        }
        fmt.Println()
}

func (l *SeqList) GetElem(i int) (e interface{}) {
        if i <= 0 || i > l.Length {
                return 0
        } else {
                return l.Data[i]
        }
}

func (l *SeqList) LocalElem(e interface{}) (i int) {
        i = 0
        for e != l.Data[i] {
                i++
                if i > l.Length {
                        break
                }
        }
        if i > l.Length {
                return -1
        } else {
                return i
        }
}

func (l *SeqList) Insert(i int, e interface{}) {
        if i < 0 || i > l.Length+1 || l.Length == MaxSize {
                panic(errors.New("No Insert!\n"))
        } else {
                for j := l.Length; j > i; j-- {
                        l.Data[j] = l.Data[j-1]
                }
                l.Data[i] = e
                l.Length++
                fmt.Printf("%d is inserted into the list!\n", e)
        }
}

func (l *SeqList) Delete(i int) (e interface{}) {
        if i <= 0 || i > l.Length {
                panic(errors.New("No Delete!\n"))
        } else {
                for j := i; j < l.Length; j++ {
                        l.Data[j] = l.Data[j+1]
                }
                l.Length--
                fmt.Printf("%d is deleted from the list!\n", l.Data[i])
                return l.Data[i]
        }
}

func main() {
        var l Operate
        l = NewSeqList()
        l.InitList()
        arr := [...]int{5, 2, 3, 4, 7}
        l.CreateList(5, arr)
        l.DisplayList()
        l.Insert(4, 3)
        l.Insert(1, 6)
        l.Insert(2, 9)
        //l.Insert(5, 0)
        fmt.Printf("Length: %d\n", l.Len())
        l.DisplayList()
        l.Delete(1)
        l.DisplayList()
        n := l.LocalElem(4)
        fmt.Printf("Elem 4 is location is %d\n", n)
        fmt.Printf("Num 4 elem is %d\n", l.GetElem(4))
        fmt.Printf("Elem 7 is location is %d\n", l.LocalElem(7))
}

切片顺序表

(1)切片顺序表的基本操作

type Operate interface {
        CreateSliceList(n int, slice ...interface{}) error
        // 初始化顺序表
        InitList()	
        // 判断顺序表是否为空表
        IsEmpty() bool	
        // 返回顺序表的元素个数
        Len() int
        // 输出顺序表
        DisplayList()
        //  获取顺序表的第 i 个元素 e
        GetElem(i int) (e interface{})
        // 查找顺序表的元素 e
        LocalElem(e interface{}) (i int)
        // 在顺序表中的第 i 个位置上插入元素 e
        Insert(i int, e interface{})
        // 从顺序表中删除第 i 个元素 e
        Delete(i int) (e interface{})
}

(2)完整程序代码

package main

import (
        "errors"
        "fmt"
)

type SliceList struct {
        Data   []interface{}
        Length int
}

func NewSliceList() *SliceList {
        return &SliceList{Data: make([]interface{}, 20, 30)}
}

type Operate interface {
        CreateSliceList(n int, slice []int) error
        InitLinkedList()
        IsEmpty() bool
        Len() int
        DisplayList()
        GetElem(i int) (e interface{})
        LocalElem(e interface{}) (i int)
        Insert(i int, e interface{})
        Delete(i int) (e interface{})
}

func (l *SliceList) InitLinkedList() {
        l.Length = 0
}

func (l *SliceList) CreateSliceList(n int, slice []int) error {
        if n <= 0 {
                return errors.New("No Create The List!\n")
        }
        for i := 0; i < n; i++ {
                l.Data[i] = slice[i]
        }
        l.Length = n
        return nil
}

func (l *SliceList) IsEmpty() bool {
        return l.Length == 0
}

func (l *SliceList) Len() int {
        return l.Length
}

func (l *SliceList) DisplayList() {
        for i := 0; i < l.Length; i++ {
                fmt.Printf("%d ", l.Data[i])
        }
        fmt.Println()
}

func (l *SliceList) GetElem(i int) (e interface{}) {
        if i <= 0 || i > l.Length {
                panic(errors.New("Search error!\n"))
        } else {
                return l.Data[i]
        }
}

func (l *SliceList) LocalElem(e interface{}) (i int) {
        i = 0
        for e != l.Data[i] {
                i++
                if i > l.Length {
                        break
                }
        }
        if i > l.Length {
                fmt.Printf("Not Found!\n")
                return -1
        } else {
                return i
        }
}

func (l *SliceList) Insert(i int, e interface{}) {
        if i < 0 || i > l.Length+1 {
                panic(errors.New("Insert is Fieled!\n"))
        }

        for j := l.Length; j > i; j-- {
                l.Data[j] = l.Data[j-1]
        }
        l.Data[i] = e
        l.Length++
        /*
                tmp := l.Data
                l.Data = append(l.Data[:i], e)
                l.Data = append(l.Data, tmp[i+1:])
                l.Length++
        */
        fmt.Printf("%d is Inserted into the SliceList!\n", e)
}

func (l *SliceList) Delete(i int) (e interface{}) {
        if i <= 0 || i > l.Length+1 {
                panic(errors.New("Delete is Feiled\n"))
        }
        tmp := l.Data
        l.Data = tmp[:i]
        l.Data = append(tmp, tmp[i:])
        l.Length--
        return e
}

func main() {
        var l Operate
        l = NewSliceList()
        l.InitLinkedList()
        list := []int{2, 3, 5, 6, 4}
        l.CreateSliceList(5, list)
        l.DisplayList()
        l.Insert(0, 6)
        l.Insert(1, 1)
        l.Insert(2, 2)
        l.DisplayList()
        fmt.Printf("SliceList Length is %d\n", l.Len())
        l.Delete(1)
        l.DisplayList()
        n := l.LocalElem(4)
        fmt.Printf("Elem 4 is location is %d\n", n)
        fmt.Printf("Num 4 elem is %d\n", l.GetElem(4))
        fmt.Printf("Elem 7 is location is %d\n", l.LocalElem(7))

}

单链表

(1)单链表的基本操作

type Operate interface {
		// 初始化链表 
        InitList()
        // 判断链表是否为空表
        IsEmpty() bool
        GetValue() interface{}
        // 返回链表的元素个数
        Len() int
        // 输出链表
        DisplayList()
        // 在链表中的第 i 个位置上插入元素 e
        Insert(pos int, v interface{}) error
        // 从链表中删除第 i 个元素 e
        Delete(pos int) (v interface{}, err error)       
}

(2)完整程序代码

package main

import (
        "errors"
        "fmt"
)

type LinkedListNode struct {
        Data interface{}
        Next *LinkedListNode
}

type LinkedList struct {
        Head   *LinkedListNode
        Length int
}

func NewLinkedListNode() *LinkedListNode {
        //return &LinkedListNode{Data: v}
        return new(LinkedListNode)
}

func NewLinkedList() *LinkedList {
        return &LinkedList{Head: &LinkedListNode{0, nil}}
}

type Operate interface {
        InitList()
        IsEmpty() bool
        GetValue() interface{}
        Len() int
        DisplayList()
        Insert(pos int, v interface{}) error
        Delete(pos int) (v interface{}, err error)
}

func (l *LinkedList) InitList() {
        l.Head.Next = nil
}

func (l *LinkedList) GetValue() interface{} {
        return l.Head.Data
}

func (l *LinkedList) IsEmpty() bool {
        return (l.Head.Next == nil)
}

func (l *LinkedList) Len() int {
        head := l.Head
        if head.Next == nil {
                return -1
        } else {
                count := 0
                for head.Next != nil {
                        count++
                        head = head.Next
                }
                return count
        }
}

func (l *LinkedList) DisplayList() {
        head := l.Head.Next
        for i := 1; head != nil; i++ {
                fmt.Printf("%d ", head.Data)
                head = head.Next
        }
        fmt.Println()
}

func (l *LinkedList) Insert(i int, v interface{}) error {
        head := l.Head
        //s := New()
        if i < 0 {
                return errors.New("No Insert\n")
        }
        for j := 0; j < i-1 && head != nil; j++ {
                head = head.Next
        }
        if head == nil {
                return errors.New("Not found!\n")
        } else {
                s := NewLinkedListNode()
                s.Data = v
                s.Next = head.Next
                head.Next = s
                l.Length++
                fmt.Printf("%d is inserted into the LinkedList!\n", v)
                return nil
        }
}

func (l *LinkedList) Delete(i int) (v interface{}, err error) {
        head := l.Head
        if i < 0 {
                return -1, errors.New("No Delete!\n")
        }
        for j := 0; j < i-1 && head != nil; j++ {
                head = head.Next
        }
        if head == nil {
                return -1, errors.New("Not Found!\n")
        } else {
                q := head.Next
                if q == nil {
                        return -1, errors.New("Not Found Node\n")
                } else {
                        v = q.Data
                        head.Next = q.Next
                        l.Length--
                        fmt.Printf("%d is deleted from the LinkedList!\n", v)
                        return v, nil
                }
        }
}

func main() {
        var l Operate
        l = NewLinkedList()
        l.InitList()
        //l.InsertElem(0, 1)
        l.Insert(1, 3)
        l.Insert(2, 2)
        l.Insert(3, 1)
        l.DisplayList()
        fmt.Printf("Linkedlist's Length is %d\n", l.Len())
        l.Delete(1)
        l.DisplayList()
}

双链表

(1)双链表的基本操作

type Operate interface {
		// 初始化链表 
        InitLinkedList()
        // 判断链表是否为空表
        IsEmpty() bool
        // 返回链表的元素个数
        Len() int
        GetLength() int
        // 输出链表
        DisplayList()
        // 在链表中的第 i 个位置上插入元素 e
        Insert(pos int, v interface{}) error
        // 从链表中删除第 i 个元素 e
        Delete(pos int) (v interface{}, err error)       
}

(2)完整程序代码

package main

import (
        "errors"
        "fmt"
)

type LinkedListNode struct {
        Data interface{}
        Prev *LinkedListNode
        Next *LinkedListNode
}

type LinkedList struct {
        Head *LinkedListNode
        //Tail *LinkedListNode
        Length int
}

func NewLinkedListNode() *LinkedListNode {
        return new(LinkedListNode)
}

func NewLinkedList() *LinkedList {
        return &LinkedList{Head: new(LinkedListNode)}
}

type Operate interface {
        InitLinkedList()
        IsEmpty() bool
        Len() int
        GetLength() int
        DisplayList()
        //GetElem(pos int) interface{}
        //LocalElem(v interface{}) int
        Insert(pos int, v interface{})
        Delete(pos int) interface{}
}

func (l *LinkedList) InitLinkedList() {
        l.Head = nil
        l.Length = 0
}

func (l *LinkedList) IsEmpty() bool {
        return l.Head == nil && l.Length == 0
}

func (l *LinkedList) CreateFrontList(arr ...interface{}) {
        l.InitLinkedList()
        p := l.Head
        var s *LinkedListNode
        for _, value := range arr {
                s = NewLinkedListNode()
                s.Data = value
                s.Next = p.Next
                if p.Next != nil {
                        p.Next.Prev = s
                }
                s.Prev = p
                p.Next = s
        }
}

func (l *LinkedList) CreateRearList(arr ...interface{}) {
        l.InitLinkedList()
        r := l.Head
        var s *LinkedListNode
        for _, value := range arr {
                s = NewLinkedListNode()
                s.Data = value
                r.Next = s
                s.Prev = r
                r = s
        }
        r.Next = nil
}

func (l *LinkedList) Len() int {
        return l.Length
}

func (l *LinkedList) GetLength() int {
        count := 0
        p := l.Head.Next
        for p != nil {
                count++
                p = p.Next
        }
        return count
}

func (l *LinkedList) DisplayList() {
        tmp := l.Head.Next
        for tmp != nil {
                fmt.Printf("%d ", tmp.Data)
                tmp = tmp.Next
        }
        fmt.Println()
}

func (l *LinkedList) Insert(pos int, v interface{}) {
        p := l.Head
        if pos <= 0 {
                panic(errors.New("No Insert!\n"))
        }
        for i := 0; i < pos-1 && p != nil; i++ {
                p = p.Next
        }
        //p = p.Next
        if p == nil {
                panic(errors.New("No Found i-1 Node!\n"))
        } else {
                s := NewLinkedListNode()
                s.Data = v
                s.Next = p.Next
                if p.Next != nil {
                        p.Next.Prev = s
                }
                s.Prev = p
                p.Next = s
                fmt.Printf("%d is insert into the LinkedList!\n", v)
                l.Length++
        }
}

func (l *LinkedList) Delete(pos int) interface{} {
        var i int = 0
        p := l.Head
        if pos <= 0 {
                panic(errors.New("No Delete!\n"))
        }
        for i < pos-1 && p != nil {
                i++
                p = p.Next
        }
        if p == nil {
                panic(errors.New("No Found i-1 Node!\n!\n"))
        } else {
                q := p.Next
                if q == nil {
                        panic(errors.New("No Found i Node!\n"))
                }
                v := q.Data
                p.Next = q.Next
                if p.Next != nil {
                        p.Next.Prev = p
                }
                l.Length--
                fmt.Printf("%d is deleted from the LinkedList!\n", v)
                return v
        }
}

func main() {
        var l Operate
        l = NewLinkedList()
        l.Insert(1, 2)
        l.Insert(2, 3)
        l.Insert(3, 6)
        l.Insert(4, 0)
        l.DisplayList()
        fmt.Printf("LinkedList Length is %d / %d\n", l.Len(), l.GetLength())
        l.Delete(3)
        l.DisplayList()
}

  • 参考书籍:《数据结构教程 第6版》(李春葆 主编)

  • 参考书籍:《数据结构 C语言版》(严蔚敏、李冬梅、吴伟民著)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

물の韜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值