一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - C/C++ - C語言 數據結構之數組模擬實現順序表流程詳解

C語言 數據結構之數組模擬實現順序表流程詳解

2022-02-28 14:54Ersansui C/C++

順序表,全名順序存儲結構,是線性表的一種,線性表用于存儲邏輯關系為“一對一”的數據,順序表自然也不例外,不僅如此,順序表對數據的物理存儲結構也有要求,跟隨下文來具體了解吧

代碼已經放在Gitee上,需要可以小伙伴可以去看看

C語言數組模擬實現順序表

Gitee

線性表和順序表

線性表

線性表(linear list)是n個具有相同特性的數據元素的有限序列,這是我們廣泛使用的數據結構

線性表在邏輯上是線性結構,也就說是連續的一條直線。但是在物理結構上并不一定是連續的,線性表在物理上存儲時,通常以數組和鏈式結構的形式存儲。

常見的線性表:順序表、鏈表、棧、隊列、字符串…

C語言 數據結構之數組模擬實現順序表流程詳解

順序表

順序表是用一段物理地址連續的存儲單元依次存儲數據元素的線性結構,一般情況下采用數組存儲。在數組上完成數據的增刪查改。

一般可以分為:

  • 靜態順序表:使用定長數組來存儲元素
  • 動態順序表:使用動態開辟的數組來儲存元素

靜態順序表

?
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
//定義靜態數組的大小,方便后續修改
#define MAX_SIZE 50
 
//重命名數組的數據類型,方便后續修改
typedef int SLDataType;
 
 
//定義結構體
//成員變量為數組和記錄當前數據個數的變量
//重命名結構體數據類型,方便書寫
typedef struct SeqList {
 
    SLDataType arr[MAX_SIZE];
    int size;
 
}SL;
 
 
//-----------------------------------------------------------------------------
//以下是一些常見的接口的聲明
 
//順序表初始化
//利用結構體類型創建一個靜態順序表變量后,可以對其進行初始化
void SLInit(SL* psl);
 
//打印順序表
//把順序表的值按照先后順序打印出來
void SLPrint(SL* psl);
 
//檢查順序表是否已滿
//每次進行加入數據的操作的時候需要先檢查是否已經滿了,如果滿了就不能夠插入了
void SLCheck(SL* psl);
 
//順序表的尾插
//在順序表的尾部在插入一個元素
//由于是數組加入數據很方便,直接使用數組下標就可以訪問到
void SLPushBack(SL* psl, SLDataType data);
 
//順序表的尾刪
//刪除順序表尾部的數據
void  SLPopBack(SL* psl);
 
//順序表的頭插
//在順序表的開頭加入一個數據
void SLPushFront(SL* psl, SLDataType data);
 
//順序表的頭刪
//把順序表第一位數據刪除
void SLPopFront(SL* psl);
 
//順序表查找某個數據
//查找順序表中是否存在某個數據,如果有就返回對應的下標
//如果找不到就返回-1
int SLFind(SL* psl, SLDataType x);
 
//順序表在pos位置插入x
//在指定下標位置插入數據x,原來x位置的數據以及后面的數據往后移動
void SLInsert(SL* psl, size_t pos, SLDataType x);
 
//順序表刪除在pos位置的數據
void SLErase(SL* psl, size_t pos);
 
//順序表某一位置數據的修改
void SLModify(SL* psl, size_t pos, SLDataType x);

以下是這些接口的具體實現

?
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
//順序表初始化
void SLInit(SL* psl) {
 
    psl->arr[0] = 0;//此處只能初始化一個元素
    psl->size = 0;
}
 
//打印順序表
void SLPrint(SL* psl) {
 
    int i = 0;
 
    if (psl->size) {
 
        for (i = 0; i < psl->size; i++) {
 
            //輸出格式,記得根據SLDataTyped的類型來修改
            printf("%d ", psl->arr[i]);
        }
        printf("\n");
    }
    else {
        printf("Null\n");
    }
 
}
 
/*
//檢查順序表是否已滿
void SLCheck(SL* psl) {
 
    if (psl->size == MAX_SIZE) {
        printf("順序表已滿,無法進行后續操作");
    }
 
}
*/
 
//順序表的尾插
void SLPushBack(SL* psl, SLDataType data) {
 
    //插入數據要先檢查空間是否已滿
 
    //實現方法一不夠好
    /*
    if (psl->size == MAX_SIZE) {
 
        printf("空間已滿\n");
        return;
    }
    else {
 
        psl->arr[psl->size] = data;
        psl->size++;
 
    }*/
 
    //實現方法二,簡單明了
    assert(psl->size != MAX_SIZE);
 
    psl->arr[psl->size] = data;
    psl->size++;
}
 
//順序表的尾刪
void  SLPopBack(SL* psl) {
 
    //判斷是否還有元素可以刪除
    assert(psl->size);
 
    psl->size--;
 
}
 
//順序表的頭插
void SLPushFront(SL* psl, SLDataType data) {
 
    assert(psl->size != MAX_SIZE);
 
    //src用來后移數據
    int src = psl->size;
 
    while (src >= 1) {
        psl->arr[src] = psl->arr[src - 1];
        src--;
    }
    psl->arr[src] = data;
    psl->size++;
 
}
 
//順序表的頭刪
void SLPopFront(SL* psl) {
 
    //判斷是否還有數據可以刪除
    assert(psl->size);
 
    int src = 0;
    while (src < psl->size - 1) {
 
        psl->arr[src] = psl->arr[src + 1];
        src++;
    }
    psl->size--;
}
 
//順序表查找某個數據
int SLFind(SL* psl, SLDataType x) {
 
    int i = 0;
    for (i = 0; i < psl->size; i++) {
        
        if (psl->arr[i] == x) {
 
            //找到了就返回該數據在順序表中的位置
            return  i;
        }
    }
    //找不到就返回-1
    return -1;
 
}
 
//順序表在pos位置插入x
void SLInsert(SL* psl, size_t pos, SLDataType x) {
 
    assert(psl->size < MAX_SIZE);
    assert(pos >= 0 && pos <= psl->size);//pos=0或者pos=size的時候,相當于頭插,尾插
 
    int end = psl->size;
 
    while (end > pos) {
 
        psl->arr[end] = psl->arr[end - 1];
        end--;
    }
    psl->arr[pos] = x;
    psl->size++;
 
}
 
//順序表刪除在pos位置的數據
void SLErase(SL* psl, size_t pos) {
 
    assert(psl->size);
    assert(pos >= 0 && pos < psl->size);
 
    int start = pos + 1;
    while (start < psl->size) {
 
        psl->arr[start - 1] = psl->arr[start];
        start++;
 
    }
    psl->size--;
}
 
 
//順序表某一位置數據的修改
void SLModify(SL* psl, size_t pos, SLDataType x) {
 
    assert(psl->size);
    assert(pos >= 0 && pos < psl->size);
 
    psl->arr[pos] = x;
}

上面代碼的測試,我放在了Gitee上,需要的小伙伴可以參考一下

動態順序表

靜態順序表只適用于確定知道需要存多少數據的場景。靜態順序表的定長數組導致N定大了,空間開多了浪費,開少了不夠用。所以現實中基本都是使用動態順序表,根據需要動態的分配空間大小,所以下面我們實現動態順序表。

?
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
//重命名SL的數據類型,方便后續修改
typedef int SLDataType;
 
//定義結構體
//成員變量為指向動態順序表的指針,數據的個數,順序表的容量
//capacity用來管理數組的總大小,如果size與capacity相等了,就表示數組已經滿了需要擴容
//重定義結構體類型名稱,方便操作
typedef struct SeqList {
 
    SLDataType* p;
    int size;
    int capacity;
 
}SL;
 
 
 
//----------------------------------------------------------------------
//一下是一些常用的接口,與靜態順序表差不多
 
//SL初始化
void SLInit(SL* ps);
 
 
//SL空間檢查
//如若size與capacity相等表示數組已經滿了,需要擴容
void SLCheckCapacity(SL* ps);
 
 
//SL打印
void SLPrint(SL* ps);
 
 
//SL銷毀
//因為數組是動態開辟的,所以在最后不使用的數組的時候要釋放空間
void SLDestory(SL* ps);
 
 
//SL尾插
void SLPushBack(SL* ps,SLDataType x);
 
 
//SL尾刪
void SLPopBack(SL* ps);
 
 
//SL頭插
void SLPushFront(SL* ps, SLDataType x);
 
 
//SL頭刪
void SLPopFront(SL* ps);
 
 
//SL查找某個數據
//如果能找到,返回該數據在順序表中下標
int SLFind(SL* ps, SLDataType x);
 
 
//SL在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);
 
 
//SL刪除pos位置的值
void SLErase(SL* ps, size_t pos);
 
 
//SL修改某一位置的數據
void SLModity(SL* ps, size_t pos, SLDataType x);

以下是具體的實現

?
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
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//動態順序表的實現
 
#include"DynamicSeqList.h"
 
//SL初始化
void SLInit(SL* ps) {
 
    ps->p = NULL;
    ps->capacity = 0;
    ps->size = 0;
 
}
 
 
//SL空間檢查
void SLCheckCapacity(SL* ps) {
 
    if (ps->size == ps->capacity) {
 
        ps->capacity = (ps->capacity == 0) ? 5 : 2 * ps->capacity;
 
        SLDataType* tmp = (SLDataType*)realloc(ps->p, (ps->capacity) * sizeof(SLDataType));
 
        if (tmp == NULL) {
 
            printf("realloc fail\n");
            exit(-1);
        }
 
        ps->p = tmp;
 
    }
 
}
 
 
//SL打印
void SLPrint(SL* ps) {
 
    if (ps->size == 0) {
 
        printf("順序表為空\n");
 
    }
    else {
 
        int i = 0;
        for (i = 0; i < ps->size; i++) {
 
            //打印格式記得根據SLDataType的類型來修改
            printf("%d ", ps->p[i]);
 
        }
        printf("\n");
 
    }
 
}
 
 
//SL銷毀
//這里并沒有完全銷毀結構體s,只是把成員變量都賦值為0
void SLDestory(SL* ps) {
 
    free(ps->p);
    ps->p = NULL;
    ps->size = ps->capacity = 0;
 
}
 
 
//SL尾插
void SLPushBack(SL* ps, SLDataType x) {
 
    SLCheckCapacity(ps);
 
    ps->p[ps->size] = x;
    ps->size++;
 
}
 
 
//SL尾刪
void SLPopBack(SL* ps) {
 
    //刪除數據需要判斷一下順序表是否為空
    assert(ps->size > 0);
    ps->size--;
 
}
 
 
//SL頭插
void SLPushFront(SL* ps, SLDataType x) {
 
    SLCheckCapacity(ps);
 
    int end = ps->size;
    while (end > 0) {
 
        ps->p[end] = ps->p[end - 1];
        end--;
 
    }
    ps->p[end] = x;
    ps->size++;
}
 
 
//SL頭刪
void SLPopFront(SL* ps) {
 
    //刪除數據需要判斷一下順序表是否為空
    assert(ps->size > 0);
 
    int start = 0;
    while (start < ps->size - 1) {
 
        ps->p[start] = ps->p[start + 1];
        start++;
 
    }
    ps->size--;
 
}
 
 
//SL查找某個數據
int  SLFind(SL* ps, SLDataType x) {
 
    //需要判斷順序表是否為空,可以用assert,也可以用if判斷
    assert(ps->size);
 
    int i = 0;
    for (i = 0; i < ps->size; i++) {
 
        if (x == ps->p[i]) {
 
            return i;
        }
 
    }
    return -1;
 
}
 
 
//SL在pos位置插入x
//當pos為0或者pos為size時,相當于頭插、尾插
void SLInsert(SL* ps, size_t pos, SLDataType x) {
 
    SLCheckCapacity(ps);
 
    assert(pos >= 0 && pos <= ps->size);
 
    int end = ps->size;
    while (end > pos) {
 
        ps->p[end] = ps->p[end - 1];
        end--;
    }
    ps->p[end] = x;
    ps->size++;
 
}
 
 
//SL刪除pos位置的值
void SLErase(SL* ps, size_t pos) {
 
    //判斷要刪除的位置是否在size之內
    assert(pos >= 0 && pos < ps->size);
 
    int start = pos + 1;
    while (start < ps->size) {
 
        ps->p[start - 1] = ps->p[start];
        start++;
 
    }
    ps->size--;
 
}
 
 
//SL修改某一位置的數據
void SLModity(SL* ps, size_t pos, SLDataType x) {
 
    //判斷要修改的位置是否在size之內
    assert(pos >= 0 && pos < ps->size);
 
    ps->p[pos] = x;
}

同樣的,我自己寫的一些小測試也在Gitee上,需要的小伙伴可以去看看

到此這篇關于C語言 數據結構之數組模擬實現順序表流程詳解的文章就介紹到這了,更多相關數組模擬實現順序表內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

原文鏈接:https://blog.csdn.net/weixin_61021362/article/details/121411921

延伸 · 閱讀

精彩推薦
  • C/C++C/C++經典實例之模擬計算器示例代碼

    C/C++經典實例之模擬計算器示例代碼

    最近在看到的一個需求,本以為比較簡單,但花了不少時間,所以下面這篇文章主要給大家介紹了關于C/C++經典實例之模擬計算器的相關資料,文中通過示...

    jia150610152021-06-07
  • C/C++深入理解goto語句的替代實現方式分析

    深入理解goto語句的替代實現方式分析

    本篇文章是對goto語句的替代實現方式進行了詳細的分析介紹,需要的朋友參考下...

    C語言教程網7342020-12-03
  • C/C++詳解c語言中的 strcpy和strncpy字符串函數使用

    詳解c語言中的 strcpy和strncpy字符串函數使用

    strcpy 和strcnpy函數是字符串復制函數。接下來通過本文給大家介紹c語言中的strcpy和strncpy字符串函數使用,感興趣的朋友跟隨小編要求看看吧...

    spring-go5642021-07-02
  • C/C++C語言中炫酷的文件操作實例詳解

    C語言中炫酷的文件操作實例詳解

    內存中的數據都是暫時的,當程序結束時,它們都將丟失,為了永久性的保存大量的數據,C語言提供了對文件的操作,這篇文章主要給大家介紹了關于C語言中文件...

    針眼_6702022-01-24
  • C/C++C語言實現電腦關機程序

    C語言實現電腦關機程序

    這篇文章主要為大家詳細介紹了C語言實現電腦關機程序,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下...

    xiaocaidayong8482021-08-20
  • C/C++c++ 單線程實現同時監聽多個端口

    c++ 單線程實現同時監聽多個端口

    這篇文章主要介紹了c++ 單線程實現同時監聽多個端口的方法,幫助大家更好的理解和學習使用c++,感興趣的朋友可以了解下...

    源之緣11542021-10-27
  • C/C++C++之重載 重定義與重寫用法詳解

    C++之重載 重定義與重寫用法詳解

    這篇文章主要介紹了C++之重載 重定義與重寫用法詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參考下...

    青山的青6062022-01-04
  • C/C++學習C++編程的必備軟件

    學習C++編程的必備軟件

    本文給大家分享的是作者在學習使用C++進行編程的時候所用到的一些常用的軟件,這里推薦給大家...

    謝恩銘10102021-05-08
主站蜘蛛池模板: 日韩亚洲人成在线综合 | 国产精品拍拍拍福利在线观看 | 2020年国产精品午夜福利在线观看 | 好湿好紧好多水c | 婷婷精品进入 | 免费视频专区一国产盗摄 | 思久久 | 美女脱了内裤打开腿让人羞羞软件 | 成人福利在线视频免费观看 | a级影视| 四虎网站入口 | 黑人异族日本人hd | 好紧好爽范冰冰系列 | 国产chinese男男gaygay | 亚洲欧美日韩一区成人 | aaa毛片手机在线现看 | 精品在线91 | 性做久久久久久 | 四虎国产精品免费久久麻豆 | 亚洲国产高清视频 | 天堂俺去俺来也www久久婷婷 | 私人影院在线播放 | 日本在线亚州精品视频在线 | 十六一下岁女子毛片免费 | 国产成人精品一区二三区 | 无遮无挡免费视频 | 99久久精品免费精品国产 | 四虎影视在线影院在线观看观看 | 日本加勒比无码av | 国产自产在线 | 果冻传媒mv在线观看入口免费 | 国产一区二区在线观看美女 | 果冻传媒第一二三专区 | 亚洲小视频网站 | 久久99国产视频 | leslessexvideos日本 | 久久精品国产在热亚洲完整版 | 百合互慰吃奶互揉漫画 | 四虎影视国产精品婷婷 | 亚洲国内精品 | 26uuu久久 |