线性表 —— 顺序存储

线性表的顺序存储:

线性表顺序存储结构的定义:

1 #include <stdio.h>
2 #include <stdlib.h>
3 #define MAXSIZE 100
4 typedef int ElemType; /*给int类型定义一个别名*/
5 typedef struct {
6     ElemType elem[MAXSIZE];/*线性表占用的数组空间*/
7     int last;/*记录线性表中最后一个元素在数组中elem[]中的位置(下标值),空表置为-1*/
8 }Seqlist;

 

顺序表的初始化:

 1 Seqlist* InitList() {
 2     /* 将SeqList大小的数据动态的分配给指针*L,(SeqList*)强制转换成指针类型*/
 3     Seqlist* L = (Seqlist*)malloc(sizeof(Seqlist));
 4     L->last = -1;
 5     return L;
 6 }
 7 void main() {
 8     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
 9     Seqlist* L = InitList();
10 }

 

顺序表中添加元素:

1 void addList(SeqList* L, ElemType e) {
2     L->last++;
3     L->elem[L->last] = e;
4 }

 

顺序表中元素的打印:

 1 void printfList(SeqList* L) {
 2     for (int i = 0; i <=L->last; i++)
 3     {
 4         printf("%d ", L->elem[i]);
 5     }
 6     printf("\n");
 7 }
 8 int main(){
 9     ElemType e;
10     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
11     SeqList* L = InitList();
12     
13     printf("原始数据:");
14     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
15     addList(L, 10);
16     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
17     addList(L, 20);
18     addList(L, 30);
19     addList(L, 40);
20     /*打印线性表中的元素*/
21     printfList(L);
22 }

 

顺序表中插入运算,第i元素位置前插入元素e:

 1 /*在线性表L中第i个元素之前插入一个元素e。i(1<=i<=last+2)*/
 2 int InsList(SeqList* L, int i, ElemType e) {
 3     int k;
 4     /*
 5     当元素i小于线性表中的第一个元素时,不能在第一个元素之前插入
 6     或线性表中有4个元素,最后一个元素的地址L->last=3。
 7     L->last+2=5,若i>5,不能插入;若插入造成不连续性,不属于线性表了
 8     */
 9     if (i<1 || i>L->last + 2)
10     {
11         printf("插入位置i值不合法");
12         return ERROR;
13     }
14     /*
15     若L->last=99,游标为99的属于线性表中的最后一个元素。
16      插入一个元素,在其后的元素后移,造成存储大小不够,线性表的存储范围(0~99)
17      */
18     if (L->last >= MAXSIZE - 1)
19     {
20         printf("表已满,无法插入");
21         return ERROR;
22     }
23     /*
24     L->last=3; k>=i-1,i=2,所以k>=1
25     */
26     for (k = L->last; k >= i - 1; k--)
27     {
28         /*
29         * 循环一次将L->elem[3]的元素赋值给L->elem[4],即元素后移
30         * 循环第二次k-1=2,将L->elem[2]的元素赋值给L->elem[3]
31         * 循环第三次k-1=1,将L->elem[1]的元素赋值给L->elem[2]
32         * 循环结束k-1=0,结束循环
33         */
34         L->elem[k + 1] = L->elem[k];
35     }
36     /*因为L->elem[1]的元素后移到L->elem[2],L->elem[1]的位置就空出来了,可以向其添加数据*/
37     L->elem[i - 1] = e;   /*第i个元素的下标为i-1*/
38     /*因为增加了一个元素,所以游标跟着变化由L->last=3变为L->last=4*/
39     L->last++;
40     return OK;
41 }
42 int main() {
43     ElemType e;
44     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
45     SeqList* L = InitList();
46 
47     printf("原始数据:");
48     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
49     addList(L, 10);
50     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
51     addList(L, 20);
52     addList(L, 30);
53     addList(L, 40);
54     /*打印线性表中的元素*/
55     printfList(L);
56 
57     printf("添加数据:");
58     InsList(L, 2, 100);
59     printfList(L);
60     return 0;
61 }

 

顺序表的删除运算,删除第i个数据元素:

 1 /*在顺序表L中删除第i个数据元素。i(1<=i<=L->last+1)*/
 2 int DelList(SeqList* L, int i, ElemType* e) {
 3     int k;
 4     if (i<1 || i>L->last + 1) {
 5         printf("删除位置不合法!");
 6         return ERROR;
 7     }
 8     *e = L->elem[i - 1]; /*将删除的元素存放到e所指向的变量中*/
 9     /*k=2;L->last=4;k<=4*/
10     for (k = i; k <= L->last; k++)
11     {
12         /*后面元素向前移动和添加一个元素类似*/
13         L->elem[k - 1] = L->elem[k];
14     }
15     /*删除一个元素游标减1*/
16     L->last--;
17     return OK;
18 }
19 int main() {
20     ElemType e;
21     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
22     SeqList* L = InitList();
23 
24     printf("原始数据:");
25     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
26     addList(L, 10);
27     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
28     addList(L, 20);
29     addList(L, 30);
30     addList(L, 40);
31     /*打印线性表中的元素*/
32     printfList(L);
33 
34     printf("添加数据:");
35     InsList(L, 2, 100);
36     printfList(L);
37 
38     printf("删除数据:");
39     DelList(L, 2, &e);
40     printfList(L);
41     return 042 }

 

顺序表的按内容查找运算,查找与e相等的元素:

 1 /* 在顺序表L中查找与e相等的元素,若L->elem[i]=e,则找到该元素,并返回元素的下标i,若找不到返回-1*/
 2 int Locate(SeqList* L, ElemType e) {
 3     int i = 0;
 4     while (i <= L->last && L->elem[i] != e)
 5     {
 6         i++;
 7     }
 8     if (i <= L->last)
 9     {
10         return (i);
11     }
12     else
13     {
14         return (-1);
15     }
16 }
17 int main() {
18     ElemType e;
19     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
20     SeqList* L = InitList();
21 
22     printf("原始数据:");
23     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
24     addList(L, 10);
25     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
26     addList(L, 20);
27     addList(L, 30);
28     addList(L, 40);
29     /*打印线性表中的元素*/
30     printfList(L);
31 
32     printf("添加数据:");
33     InsList(L, 2, 100);
34     printfList(L);
35 
36     printf("删除数据:");
37     DelList(L, 2, &e);
38     printfList(L);
39 
40     printf("查找数据的位置:");
41     int n = Locate(L, 20);
42     if (n<0)
43     {
44         printf("没找到");
45     }
46     else {
47         printf("%d ",n + 1);
48         printf("查找的数:%d\n", L->elem[n]);
49     }
50     return 0;
51 }

 

顺序表中插入一个元素e,插入元素后,保障顺序表还是有序:

 1 /*插入一个元素,保障线性表的有序性*/
 2 int InsOrderList(SeqList* L, ElemType e) {
 3     int i;
 4     for (i = L->last;i >= 0;i--) {
 5         if (L->elem[i]>e) {
 6             L->elem[i + 1] = L->elem[i];
 7         }
 8         else {
 9             break;
10         }
11     }
12     L->elem[i + 1] = e;
13     L->last++;
14     return OK;
15 }
16 int main() {
17     ElemType e;
18     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
19     SeqList* L = InitList();
20 
21     printf("原始数据:");
22     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
23     addList(L, 10);
24     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
25     addList(L, 20);
26     addList(L, 30);
27     addList(L, 40);
28     /*打印线性表中的元素*/
29     printfList(L);
30 
31     printf("添加数据:");
32     InsList(L, 2, 100);
33     printfList(L);
34 
35     printf("删除数据:");
36     DelList(L, 2, &e);
37     printfList(L);
38 
39     printf("查找数据的位置:");
40     int n = Locate(L, 20);
41     if (n<0)
42     {
43         printf("没找到");
44     }
45     else {
46         printf("%d ",n + 1);
47         printf("查找的数:%d\n", L->elem[n]);
48     }
49 
50     printf("按顺序插入元素:");
51     InsOrderList(L,150);
52     printfList(L);
53     
54     return 0;
55 }

 

顺序表操作总代码:

  1 #include <stdio.h>
  2 #include <stdlib.h>
  3 #define MAXSIZE 100
  4 #define OK 1
  5 #define ERROR 0
  6 typedef int ElemType;
  7 typedef struct {
  8     ElemType elem[MAXSIZE];
  9     int last;
 10 }SeqList;
 11 /*初始化线性列表*/
 12 SeqList* InitList() {
 13     /*   将SeqList大小的数据动态的分配给指针*L  (SeqList*)强制转换成指针类型   */
 14     SeqList* L = (SeqList*)malloc(sizeof(SeqList));
 15     L->last = -1;
 16     return L;
 17 }
 18 /*向线性列表中添加数据*/
 19 void addList(SeqList* L, ElemType e) {
 20     L->last++;
 21     L->elem[L->last] = e;
 22 }
 23 /*打印线性列表中的数据*/
 24 void printfList(SeqList* L) {
 25     for (int i = 0; i <= L->last; i++)
 26     {
 27         printf("%d ", L->elem[i]);
 28     }
 29     printf("\n");
 30 }
 31 /*在线性表L中第i个元素之前插入一个元素e。i(1<=i<=last+2)*/
 32 int InsList(SeqList* L, int i, ElemType e) {
 33     int k;
 34     /*
 35     当元素i小于线性表中的第一个元素时,不能在第一个元素之前插入
 36     或线性表中有4个元素,最后一个元素的地址L->last=3。
 37     L->last+2=5,若i>5,不能插入;若插入造成不连续性,不属于线性表了
 38     */
 39     if (i<1 || i>L->last + 2)
 40     {
 41         printf("插入位置:值不合法");
 42         return ERROR;
 43     }
 44     /*
 45     若L->last=99,游标为99的属于线性表中的最后一个元素。
 46      插入一个元素,在其后的元素后移,造成存储大小不够,线性表的存储范围(0~99)
 47      */
 48     if (L->last >= MAXSIZE - 1)
 49     {
 50         printf("表已满,无法插入");
 51         return ERROR;
 52     }
 53     /*
 54     L->last=3; k>=i-1,i=2,所以k>=1
 55     */
 56     for (k = L->last; k >= i - 1; k--)
 57     {
 58         /*
 59         * 循环一次将L->elem[3]的元素赋值给L->elem[4],即元素后移
 60         * 循环第二次k-1=2,将L->elem[2]的元素赋值给L->elem[3]
 61         * 循环第三次k-1=1,将L->elem[1]的元素赋值给L->elem[2]
 62         * 循环结束k-1=0,结束循环
 63         */
 64         L->elem[k + 1] = L->elem[k];
 65     }
 66     /*因为L->elem[1]的元素后移到L->elem[2],L->elem[1]的位置就空出来了,可以向其添加数据*/
 67     L->elem[i - 1] = e;
 68     /*因为增加了一个元素,所以游标跟着变化由L->last=3变为L->last=4*/
 69     L->last++;
 70     return OK;
 71 }
 72 /*插入一个元素,保障线性表的有序性*/
 73 int InsOrderList(SeqList* L, ElemType e) {
 74     int i;
 75     for (i = L->last;i >= 0;i--) {
 76         if (L->elem[i]>e) {
 77             L->elem[i + 1] = L->elem[i];
 78         }
 79         else {
 80             break;
 81         }
 82     }
 83     L->elem[i + 1] = e;
 84     L->last++;
 85     return OK;
 86 }
 87 /*在顺序表L中删除第i个数据元素。i(1<=i<=L.last+1)*/
 88 int DelList(SeqList* L, int i, ElemType* e) {
 89     int k;
 90     if (i<1 || i>L->last + 1) {
 91         printf("删除位置不合法!");
 92         return ERROR;
 93     }
 94     *e = L->elem[i - 1];
 95     /*k=2;L->last=4;k<=4*/
 96     for (k = i; k <= L->last; k++)
 97     {
 98         /*后面元素向前移动和添加一个元素类似*/
 99         L->elem[k - 1] = L->elem[k];
100     }
101     /*删除一个元素游标减1*/
102     L->last--;
103     return OK;
104 }
105 /* 在顺序表L中查找与e相等的元素,若L.elem[i]=e,则找到该元素,并返回i+1,若找不到返回-1*/
106 int Locate(SeqList* L, ElemType e) {
107     int i = 0;
108     while (i <= L->last && L->elem[i] != e)
109     {
110         i++;
111     }
112     if (i <= L->last)
113     {
114         return (i);
115     }
116     else
117     {
118         return (-1);
119     }
120 }
121 
122 /*在顺序表L中查找与e相等的元素,若L.elem[i]=e*/
123 int main() {
124     ElemType e;
125     /*初始化线性表返回的是指针类型,所以主函数中要定义一个指针类型接收*/
126     SeqList* L = InitList();
127 
128     printf("原始数据:");
129     /*若调用一次该函数,L->last+1(L->last=-1变为L->last=0),并向L->last=0的地址中添加数据e=10*/
130     addList(L, 10);
131     /*若调用第二次该函数,L->last+1(L->last=0变为L->last=1),并向L->last=1的地址中添加数据e=20*/
132     addList(L, 20);
133     addList(L, 30);
134     addList(L, 40);
135     /*打印线性表中的元素*/
136     printfList(L);
137 
138     printf("添加数据:");
139     InsList(L, 2, 100);
140     printfList(L);
141 
142     printf("删除数据:");
143     DelList(L, 2, &e);
144     printfList(L);
145 
146     printf("查找数据的位置:");
147     int n = Locate(L, 20);
148     if (n<0)
149     {
150         printf("没找到");
151     }
152     else {
153         printf("%d ",n + 1);
154         printf("查找的数:%d\n", L->elem[n]);
155     }
156 
157     printf("按顺序插入元素:");
158     InsOrderList(L,150);
159     printfList(L);
160 
161 
162     return 0;
163 }

 

线性表的合并运算:

 1 #include <stdio.h>
 2 #include <stdlib.h>
 3 #define MAXSIZE 100
 4 #define OK 1
 5 #define ERROR 0
 6 typedef int ElemTyle;
 7 typedef struct {
 8     ElemTyle elem[MAXSIZE];
 9     int last;
10 }SeqList;
11 /*初始化线性表*/
12 SeqList* InitList() {
13     SeqList* L = (SeqList*)malloc(sizeof(SeqList));
14     L->last = -1;
15     return L;
16 }
17 /*向线性表中添加元素*/
18 void addList(SeqList* L, ElemTyle e) {
19     L->last++;
20     L->elem[L->last] = e;
21 }
22 /*打印线性表中的元素*/
23 void printfList(SeqList* L) {
24     for (int i = 0; i <= L->last; i++)
25     {
26         printf("%d ", L->elem[i]);
27     }
28     printf("\n");
29 }
30 /*合并线性表*/
31 int margeList(SeqList* LA, SeqList* LB, SeqList* LC) {
32     int i, j, k;
33     i = 0;j = 0;k = 0;
34     while (i<=LA->last&&j<=LB->last)
35     {
36         if (LA->elem[i]<=LB->elem[j])
37         {
38             LC->elem[k] = LA->elem[i];
39             i++;k++;
40         }
41         else
42         {
43             LC->elem[k] = LB->elem[j];
44             j++;k++;
45         }
46     }
47     while (i<=LA->last)
48     {
49         LC->elem[k] = LA->elem[i];
50         i++;k++;
51     }
52     while (j<=LB->last)
53     {
54         LC->elem[k] = LB->elem[j];
55         j++;k++;
56     }
57     LC->last = LA->last + LB->last + 1;
58     return OK;
59 }
60 int main() {
61     SeqList* LA = InitList();
62     addList(LA, 2);
63     addList(LA, 4);
64     addList(LA, 6);
65     addList(LA, 8);
66     printf("线性表LA的元素:");
67     printfList(LA);
68 
69     SeqList* LB = InitList();
70     addList(LB, 1);
71     addList(LB, 3);
72     addList(LB, 5);
73     addList(LB, 7);
74     addList(LB, 9);
75     printf("线性表LB的元素:");
76     printfList(LB);
77 
78     SeqList* LC = InitList();
79 
80     /*合并线性表*/
81     printf("线性表LC的元素:");
82     margeList(LA, LB, LC);
83     printfList(LC);
84     return 0;
85 }

 

顺序表的优点:

(1)无需为表示结点间的逻辑关系而增加额外的存储空间(因逻辑上相邻的元素其存储的物理位置也相邻)

(2)可以方便地随机存取表中的任一元素

顺序表的缺点:

(1)插入和删除不方便,除表尾外,在表的其他位置插入和删除元素,结点都需要大量的移动,效率低

(2)由于顺序表要求占用连续的存储空间,存储分配只能预先进行静态分配。当表长变得比较大时,难以确定合适的存储规模

 

posted @ 2020-10-03 20:15  笺笙  阅读(253)  评论(0编辑  收藏  举报