大家好,我是Koko~


  数据结构是计算机存储、组织数据的方式。数据结构是指相互之间存在一种或多种特定关系的数据元素的集合。通常情况下,精心选择的数据结构可以带来更高的运行或者存储效率。 数据结构往往同高效的检索算法和索引技术有关。

 

  本专栏将针对数据结构相关知识进行梳理及总结。建议搭配C语言版(严蔚敏版)数据结构教材使用更佳。

 



 

  线性表是最常用且最简单的一种数据结构。一个线性表是n个数据元素的有限序列。在稍复杂的线性表中,一个数据元素可以由若干个数据项组成。在这种情况下,常把数据元素称为记录,含有大量记录的线性表又称文件。

 

  同一线性表中的元素必定具有相同特性,即属同一数据对象,相邻数据元素之间存在着序偶关系。


1、线性结构的基本特征:  

 

  线性逻辑结构的非形式化描述          一个数据元素的有序(次序)集


(1)集合中必存在唯一的一个“第一元素”


(2)集合中必存在唯一的一个 “最后元素”


(3)除最后元素在外,均有 唯一的后继


(4)除第一元素之外,均有 唯一的前驱


2、线性表类型的存储结构----顺序映射

 

  线性表具有两种结构——顺序结构链式结构。本节主要讲解顺序结构所对应的顺序表

 

顺序映象

          以 x 的存储位置和 y 的存储位置之间某种关系表示逻辑关系<x,y>

通常情况顺序映象方法是

         令y的存储位置和x的存储位置相邻。

 

一、顺序表的定义

 

  顺序表,用一组地址连续的存储单元依次存储线性表的数据元素,它的逻辑地址相邻,物理地址也相邻(参照一维数组)。

 

1.1线性表·顺序表_线性表

 

 

  顺序表的优点:简单、支持随机访问、查找方便、尾插和尾删效率高。

  顺序表的缺点:数据的插入和删除慢(需要挪动后面的数据)。

 

  顺序表的结构如下图所示,它有两个区域,一个是数据区域类似于数组,存放用户存储的数据,另一个是一个整形变量区,存放已经使用了的区域个数。

1.1线性表·顺序表_数据_02

 

 

 定义顺序表类型

 



1 #include<stdio.h>
2 #include<stdlib.h>
3 #define MAXSIZE 20
4
5 //数据元素的类型
6 typedef int ElemType;
7
8 //定义顺序表类型
9 typedef struct
10 {
11 ElemType a[MAXSIZE];
12 int length; //顺序表的实际长度
13 }SqList, *SqList;


 二、顺序表的基本操作函数

 

  对顺序表,有初始化、打印、插入、删除、查找的基本操作。

 

1、初始化顺序表函数

 



1 Status Init_List(SqList &L)
2 {
3 memset(L.data, 0, sizeof(L));//初始化数据为0
4 L.length = 0; //初始化长度为0
5 return 0;
6 }


 

2、创建顺序表函数

 



1 //建立线性表
2 void Creat_List(SqList *L)
3 {
4 int i;
5 printf("请输入线性表的长度: ");
6 scanf("%d",&L->length);
7 for(i=0;i<L->length;i++)
8 {
9 printf("数据 %d =",i);
10 scanf("%d",&(L->a[i]));
11 }
12 }


 

3、输出函数

 



1 //输出线性表
2 void Out_List(SqList L)
3 {
4 int i;
5 for(i=0;i<=L.length-1;i++)
6 printf("%10d",L.a[i]);
7 }


 

4、插入函数(插入一个元素)

 

1.1线性表·顺序表_线性表_03

 

 



1 //在线性表的第i个位置插入元素e
2 void Insert_Sq(SqList *L,int i,ElemType e)
3 {
4 int j;
5 if(L->length==MAXSIZE)
6 printf("线性表已满!\n");
7 else
8 {
9 if(i<1||i>L->length+1)
10 printf("输入位置错!\n");
11 else
12 {
13 for(j=L->length-1;j>=i-1;j--)
14 L->a[j+1]=L->a[j];
15 L->a[i-1]=e;
16 L->length++;
17 }
18 }
19 }


 

 

 5、删除函数(删除一个元素)

 

1.1线性表·顺序表_i++_04

 

 



1 //删除第i个元素,返回其值
2 ElemType Delete_Sq(SqList *L,int i)
3 {
4 ElemType x;
5 int j;
6 if(L->length==0)
7 printf("空表!\n");
8 else if(i<1||i>L->length)
9 {
10 printf("输入位置错!\n");
11 x=-1;
12 }
13 else
14 {
15 x=L->a[i-1];
16 for(j=i;j<=L->length-1;j++)
17 L->a[j-1]=L->a[j];
18 L->length--;
19 }
20 return(x);
21 }


 

6、查找函数(查找一个值为e的元素,返回它的位置)

 

1.1线性表·顺序表_i++_05

 

 



1 //查找值为e的元素,返回它的位置
2 int Locate_Elem(SqList L,ElemType e)
3 {
4 int i=0;
5 while(L.a[i]!=e)
6 i++;
7 if(i<=L.length-1)
8 return(i+1);
9 }


 

三、顺序表的功能操作函数

 

1、倒置函数(将原顺序表直接倒置)

 



1 //倒置函数 将原顺序表直接倒置
2 void Reverse(SqList &L)
3 {
4 if (L.length)
5 for (int i = 0; i<L.length - 1 - i; i++)
6 {
7 int t = L.data[i];
8 L.data[i] = L.data[L.length - 1 - i];
9 L.data[L.length - 1 - i] = t;
10 }
11 }


 

2、奇偶分开并排序

 



1 //奇偶分开并排序
2 void SplitSort(SqList &L)
3 {
4 int Even = 0;
5 int Odd = L.length - 1;
6 int i = 0;
7 int j = L.length - 1;
8 bool flag = false;
9 if (L.length)
10 for (; i < j; i++, j--)
11 {
12 while (L.data[i] % 2 != 0)i++;
13 while (L.data[j] % 2 == 0)j--;
14 if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0&&i<j)
15 {
16 int temp = L.data[i];
17 L.data[i] = L.data[j];
18 L.data[j] = temp;
19 flag = true;
20 }
21 if(!flag) //没有交换
22 {
23 Even = L.length - 1;//全奇数
24 Odd = 0; //全偶数
25 }
26 }
27 if (flag)
28 {
29 for(int i=0;i<L.length;i++)
30 if (L.data[i] % 2 == 0)
31 {
32 Odd = i;
33 Even = i - 1;
34 break;
35 }
36 }
37 sort(L.data, L.data + Even + 1);
38 sort(L.data + Odd, L.data + L.length);
39 }


 

四、顺序表操作总览

 



1 /*
2 Project: sequence_list(数据结构-顺序表)
3 */
4
5 #include<cstdio>
6 #include<cstdlib>
7 #include<cstring>
8 #include<cmath>
9 #include<algorithm>
10 #include<iostream>
11 #define MaxSize 100
12 #define ElemType int
13 #define Status int
14 using namespace std;
15
16 //顺序表数据结构
17 typedef struct
18 {
19 ElemType a[MAXSIZE];
20 int length; //顺序表的实际长度
21 }SqList, *SqList;
22
23 //***************************基本操作函数*******************************//
24
25 //初始化顺序表函数,构造一个空的顺序表
26 Status Init_List(SqList &L)
27 {
28 memset(L.data, 0, sizeof(L));//初始化数据为0
29 L.length = 0; //初始化长度为0
30 return 0;
31 }
32
33 //创建顺序表函数 初始化前n个数据
34 void Creat_List(SqList *L)
35 {
36 int i;
37 printf("请输入线性表的长度: ");
38 scanf("%d",&L->length);
39 for(i=0;i<L->length;i++)
40 {
41 printf("数据 %d =",i);
42 scanf("%d",&(L->a[i]));
43 }
44 }
45
46 //插入函数 位置i插入数据 i及之后元素后移 1=<i<=length+1
47 void Insert_Sq(SqList *L,int i,ElemType e)
48 {
49 int j;
50 if(L->length==MAXSIZE)
51 printf("线性表已满!\n");
52 else
53 {
54 if(i<1||i>L->length+1)
55 printf("输入位置错!\n");
56 else
57 {
58 for(j=L->length-1;j>=i-1;j--)
59 L->a[j+1]=L->a[j];
60 L->a[i-1]=e;
61 L->length++;
62 }
63 }
64 }
65
66 //删除函数 删除位置i的元素 i之后的元素依次前移
67 ElemType Delete_Sq(SqList *L,int i)
68 {
69 ElemType x;
70 int j;
71 if(L->length==0)
72 printf("空表!\n");
73 else if(i<1||i>L->length)
74 {
75 printf("输入位置错!\n");
76 x=-1;
77 }
78 else
79 {
80 x=L->a[i-1];
81 for(j=i;j<=L->length-1;j++)
82 L->a[j-1]=L->a[j];
83 L->length--;
84 }
85 return(x);
86 }
87
88 //查找函数 按位置从小到大查找第一个值等于e的元素 并返回位置
89 int Locate_Elem(SqList L,ElemType e)
90 {
91 int i=0;
92 while(L.a[i]!=e)
93 i++;
94 if(i<=L.length-1)
95 return(i+1);
96 }
97
98 //倒置函数 将原顺序表直接倒置
99 void Reverse(SqList &L)
100 {
101 if (L.length)
102 for (int i = 0; i<L.length - 1 - i; i++)
103 {
104 int t = L.data[i];
105 L.data[i] = L.data[L.length - 1 - i];
106 L.data[L.length - 1 - i] = t;
107 }
108 }
109
110 //奇偶分开并排序
111 void SplitSort(SqList &L)
112 {
113 int Even = 0;
114 int Odd = L.length - 1;
115 int i = 0;
116 int j = L.length - 1;
117 bool flag = false;
118 if (L.length)
119 for (; i < j; i++, j--)
120 {
121 while (L.data[i] % 2 != 0)i++;
122 while (L.data[j] % 2 == 0)j--;
123 if (L.data[i] % 2 == 0 && L.data[j] % 2 != 0&&i<j)
124 {
125 int temp = L.data[i];
126 L.data[i] = L.data[j];
127 L.data[j] = temp;
128 flag = true;
129 }
130 if(!flag) //没有交换
131 {
132 Even = L.length - 1;//全奇数
133 Odd = 0; //全偶数
134 }
135 }
136 if (flag)
137 {
138 for(int i=0;i<L.length;i++)
139 if (L.data[i] % 2 == 0)
140 {
141 Odd = i;
142 Even = i - 1;
143 break;
144 }
145 }
146 sort(L.data, L.data + Even + 1);
147 sort(L.data + Odd, L.data + L.length);
148 }
149
150 //清空顺序表
151 void ClearList(SqList &L) {
152 L.length = 0;
153 }
154
155 //********************************功能函数*****************************************//
156
157 //输出功能函数 按位置从小到大输出顺序表所有元素
158 void Out_List(SqList L)
159 {
160 int i;
161 for(i=0;i<=L.length-1;i++)
162 printf("%10d",L.a[i]);
163 }
164
165 //创建顺序表函数
166 void Create(SqList &L)
167 {
168 int n; bool flag;
169 L.length = 0;
170 printf("请输入要创建的顺序表长度(>1):");
171 scanf("%d", &n);
172 printf("请输入%d个数(空格隔开):", n);
173 flag = CreateList(L, n);
174 if (flag) {
175 printf("创建成功!\n");
176 PrintList(L);
177 }
178 else printf("输入长度非法!\n");
179
180 }
181
182 //插入功能函数 调用Insert_Sq完成顺序表元素插入 调用Out_List函数显示插入成功后的结果
183 void Insert(SqList &L,int place, ElemType e)
184 {
185 bool flag;
186 printf("请输入要插入的位置(从1开始)及元素:\n");
187 scanf("%d%d", &place, &e);
188 flag = Insert_Sq(L, place, e);
189 if (flag)
190 {
191 printf("插入成功!!!\n");
192 PrintList(L);
193 }
194 }
195
196 //删除功能函数 调用Delete_Sq函数完成顺序表的删除 调用Out_List函数显示插入成功后的结果
197 void Delete(SqList &L,int place;)
198 {
199 bool flag;
200 printf("请输入要删除的位置(从1开始):\n");
201 scanf("%d", &place);
202 flag = Delete_Sq(L, place);
203 if (flag)
204 {
205 printf("删除成功!!!\n");
206 PrintList(L);
207 }
208 }
209
210 //查找功能函数 调用LocateElem查找元素
211 void Locate_Elem(SqList L)
212 {
213 ElemType e; int flag;
214 printf("请输入要查找的值:\n");
215 scanf("%d", &e);
216 flag = Locate_Elem(L, e);
217 if (flag)
218 {
219 printf("该元素位置为:%d\n", flag);
220 }
221 else
222 printf("未找到该元素!\n");
223 }
224
225 //菜单
226 void menu()
227 {
228 printf("********1.创建 2.插入*********\n");
229 printf("********3.删除 4.查找*********\n");
230 printf("********5.倒置 6.分奇偶排序***\n");
231 printf("********7.输出 8.清空*********\n");
232 printf("********9.退出 *********\n");
233 }
234 int main()
235 {
236 SqList L; int choice;
237 InitList(L);
238 while (1)
239 {
240 menu();
241 printf("请输入菜单序号:\n");
242 scanf("%d", &choice);
243 if (9 == choice) break;
244 switch (choice)
245 {
246 case 1:Create(L); break;
247 case 2:Insert(L); break;
248 case 3:Delete(L); break;
249 case 4:Search(L); break;
250 case 5:Reverse(L); break;
251 case 6:SplitSort(L); break;
252 case 7:PrintList(L); break;
253 case 8:ClearList(L); break;
254 default:printf("输入错误!!!\n");
255 }
256 }
257 return 0;
258 }
259


 



 


以上部分​​代码和图片如有侵权,请告知删除!​