线性表基础知识
线性表的基本概念
(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.Next 和 head.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语言版》(严蔚敏、李冬梅、吴伟民著)