线性表

线性表(Linear List):由同类型数据元素构成有序序列的线性结构,一对一

  • 表中元素的个数称为线性表的长度
  • 线性表没有元素时称为空表
  • 表起始位置称为表头,结束位置称为表尾

线性表的抽象数据类型描述

类型名称:线性表(List)

数据对象集:线性表是n(n>=0)个元素构成的有序序列(a1,a2,….an)

操作集

  • 初始化一个空线性表
  • 是否空表
  • 查找
    • 根据key返回value
    • 根据value返回第一次出现此value的key
  • 插入
  • 删除
  • 表长

线性表的实现方式

线性表的顺序存储实现(数组)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// 线性结构的数组实现
struct LinearListUseArray<T> where T : Equatable, T : Any {
    var data : [T]?
    var last : Int// 最后一个下标
    
    init() {
        data = nil
        last = -1
    }
    
    func isEmpty() -> Bool {
        return last < 0
    }
    
    func key(for value:T) -> Int {
        if isEmpty() {
            return NSNotFound
        }
        if let array = data {
            for i in 0..<array.count {
                if array[i] == value {
                    return i
                }
            }
            return NSNotFound
        }
        else {
            return NSNotFound
        }
    }
    
    func value(for key:Int) -> T? {
        if isEmpty() || key < 0 || key > last {
            return nil
        }
        return data?[key]
    }
    
    mutating func insert(value v:T, at i:Int) -> Bool {
        if i<0 || i > last || isEmpty() {
            return false
        }
        data?.insert(v, at: i)
        last += 1
        return true;
    }
    
    mutating func delete(key i:Int) -> T? {
        if i<0 || i > last || isEmpty()  {
            return nil
        }
        let v = data?.remove(at: i)
        last -= 1
        return v
    }
}

线性表的链式存储实现(链表)

  • 不要求逻辑上相邻的元素在物理存储上也相邻
  • 插入,删除不需要移动元素,只需要修改链
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
class LinearListNode<T: Hashable> {
    var data : T?
    var next : LinearListNode?
    init(data:T?) {
        self.data = data
    }
}

class LinearList<T : Hashable> {
    var head : LinearListNode<T>?
    init() {
        head = nil
    }
    
    func length() -> Int {
        var length = 0, n = head
        while (n != nil) {
            n = n!.next
            length += 1
        }
        return length
    }
    
    func findNode(number:Int) -> LinearListNode<T>? {
        var i = 0, n = head
        while n != nil && i < number {
            n = n!.next
            i += 1
        }
        if i == number {
            return n
        }
        else {
            return nil
        }
    }
    
    func findNode(data:T) -> LinearListNode<T>? {
        var n = head
        while n != nil {
            if n!.data == data {
                return n
            }
            n = n!.next
        }
        return nil
    }
    
    func insert(value:T, at i:Int) -> Void {
        let node = LinearListNode(data: value);
        if i == 0 {
            node.next = head
            head = node;
            return
        }
        
        let lastNode = findNode(number: i - 1)
        node.next = lastNode?.next
        lastNode?.next = node
    }
    
    func delete(at i:Int) -> T?{
        var temp : T? = nil
        if i == 0 {
            temp = head?.data
            head = head?.next
            return temp
        }
        
        let n = findNode(number: i - 1)
        if n == nil || n!.next == nil {
            return nil
        }
        temp = n!.next!.data
        n!.next = n!.next!.next
        return temp
    }
}

let list = LinearList<String>()
list.insert(value: "aaa", at: 0)
list.insert(value: "bbb", at: 1)
list.insert(value: "ccc", at: 2)

广义表

  • 广义表是线性表的推广
  • 线性表中,n个元素都是单元素
  • 广义表中,元素不仅可以是单元素也可以是另一个广义表
1
2
3
4
5
6
7
8
9
typedef struct GNode *GList; 
struct GNode{
    int Tag; /*标志域:0表示结点是单元素,1表示结点是广义表 */
    union { /*子表指针域Sublist与单元素数据域Data复用,即共用存储空间*/
        ElementType Data;
        GList SubList;
    } URegion;
    GList Next; /* 指向后继结点 */
};

多重链表

链表中的节点可能同时隶属于多个链

  • 多重链表中的节点的指针域会有多个,例如广义表中的Next和SubList两个指针域
  • 但包含两个指针域的链表不一定是多重链表,如双向链表不是多重链表
  • 多重链表有广泛的用途,如树,图这种复杂度数据结构都可以用多重链表的方式实现存储