資料結構:線性表之順序儲存結構

來源:互聯網
上載者:User

線性表的資料對象集合為 {a1,a2,....an},每個元素的類型均為Datatype。其中,除第一個元素a1外,每一個元素有且只有一個直接前驅元素,除了最後一個元素an外,每一個元素有且只有一個直接後繼元素。資料元素之間的關係是一對一的關係。


線性表的順序儲存結構的優缺點:

優點:無須為表示表中元素之間的邏輯關係而增加額外的儲存空間;可以快速地存取表中任一位置的元素O(1)

缺點:插入和刪除操作需要移動大量元素O(n);當線性表長度變化較大時,難以確定儲存空間的容量;造成儲存空間的“片段”


樣本程式如下(改編自《大話資料結構》):

 C++ Code 
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
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include<iostream>
using namespace std;

#define MAXSIZE 20

typedef int ElemType;

typedef struct
{
    ElemType data[MAXSIZE];
    int length;
} SqList;

/* 初始化順序線性表 */
bool InitList(SqList *ptr)
{
    for (int i = 0 ; i < MAXSIZE; i++)
        ptr->data[i] = 0;
    ptr->length = 0;
    return true;
}

bool ListEmpty(SqList Sq)
{
    if (Sq.length == 0)
        return true;
    else
        return false;
}

bool ClearList(SqList *ptr)
{
    for (int i = 0 ; i < ptr->length; i++)
        ptr->data[i] = 0;
    ptr->length = 0;
    return true;
}
/*用ptr返回Sq中第pos個資料元素的值,注意pos是指位置,第1個位置的數組是從0開始 */
bool GetElem(SqList Sq, int pos, ElemType *ptr)
{
    if (Sq.length == 0 || pos < 1 || pos > Sq.length)
        return false;
    *ptr = Sq.data[pos - 1];
    return true;
}
/*返回Sq中第1個與Elem滿足關係的資料元素的位序,若這樣的資料元素不存在,則傳回值為0 */
int Locate(SqList Sq, ElemType Elem)
{
    for (int i = 0; i < Sq.length; i++)
    {
        if (Sq.data[i] == Elem)
            return i + 1;
    }
    return 0;
}
/*在Sq中第pos個位置之前插入新的資料元素Elem,L的長度加1*/
bool ListInsert(SqList *ptr, int pos, ElemType Elem)
{
    if (ptr->length == MAXSIZE)/* 順序線性表已經滿 */
        return false;
    if (pos < 1 || pos > ptr->length + 1)
        return false;
    if (pos <= ptr->length)
    {
        /* 將要插入位置之後的資料元素向後移動一位 */
        for (int i = ptr->length - 1; i >= pos - 1; i--)
        {
            ptr->data[i + 1] = ptr->data[i];
        }
    }

    ptr->data[pos - 1] = Elem; /* 將新元素插入 */

    ptr->length++;
    return true;
}
/*刪除ps的第pos個資料元素,並用pe返回其值,ps的長度減1*/
bool ListDelete(SqList *ps, int pos, ElemType *pe)
{
    if (pos < 1 || pos > ps->length)
        return false;
    *pe = ps->data[pos - 1];
    /* 將刪除位元置後繼元素前移 */
    for (int i = pos; i < ps->length; i++)
        ps->data[i - 1] = ps->data[i];

    ps->length--;

    return true;

}

int ListLength(SqList Sq)
{
    return Sq.length;
}

/*將所有線上性表pb中但不在pa中的元素都插入到pa中*/
void UnionList(SqList *pa, SqList *pb)
{
    int lena = pa->length;
    int lenb = pb->length;
    int item;

    for (int i = 0; i < lenb; i++)
    {
        if (GetElem(*pb, i + 1, &item))
        {
            if (Locate(*pa, item) == 0)
                ListInsert(pa, ++lena, item);
        }
    }

}

int main(void)
{
    SqList Sq;
    InitList(&Sq);
    for (int i = 1 ; i < 5; i++)
        ListInsert(&Sq, i, i);

    if (!ListEmpty(Sq))
    {
        cout << "Sq: " << endl;
        for (int i = 0 ; i < ListLength(Sq); i++)
            cout << Sq.data[i] << ' ';
    }
    cout << endl;

    int pos = Locate(Sq, 2);
    if (pos != 0)
    {
        int result;
        ListDelete(&Sq, pos, &result);
        cout << "delete: " << result << endl;
    }

    if (!ListEmpty(Sq))
    {
        cout << "Sq: " << endl;
        for (int i = 0 ; i < ListLength(Sq); i++)
            cout << Sq.data[i] << ' ';
    }
    cout << endl;

    SqList Sq2;
    InitList(&Sq2);
    for (int i = 1 ; i < 4; i++)
        ListInsert(&Sq2, i, 6);
    ListInsert(&Sq2, 4, 7);
    if (!ListEmpty(Sq2))
    {
        cout << "Sq2: " << endl;
        for (int i = 0 ; i < ListLength(Sq2); i++)
            cout << Sq2.data[i] << ' ';
    }
    cout << endl;

    UnionList(&Sq, &Sq2);

    if (!ListEmpty(Sq))
    {
        cout << "Sq: " << endl;
        for (int i = 0 ; i < ListLength(Sq); i++)
            cout << Sq.data[i] << ' ';
    }
    cout << endl;

    return 0;
}

輸出為:


注意:

1、程式中所說的位置pos應是序號加1,如第一個元素序號為0,位置為1。

2、程式中所舉的函數是最基本的操作,涉及更複雜的操作可以使用基本操作的組合來完成,如上面的UnionList即求兩個線性表集合A和B的並集。

3、初學者易混淆的點是:插入或刪除並沒有真正進行記憶體的操作,只是進行了元素的移動,覆蓋等,由length成員來記錄現線上性表的長度,但總長度是確定的即MAXSIZE,線性表的記憶體在棧上,函數返回時會被釋放。



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.