顺序表的定义及其特点;
定义
顺序表是一种线性表的存储结构,它由一组连续的存储空间组成,用于存储具有相同数据类型的元素。顺序表的特点是元素在内存中的物理位置是连续的,每个元素都可以通过下标来直接访问。
-
数据元素:顺序表中的每个元素具有相同的数据类型,可以是基本数据类型(如整数、浮点数)或自定义的数据结构(如结构体)。
-
存储空间:顺序表使用一段连续的存储空间来存储元素,通常是一块连续的内存区域。
-
元素个数:顺序表中元素的个数是固定的,可以在初始化时指定最大容量,也可以动态调整大小。
-
下标访问:顺序表中的每个元素都有一个唯一的下标,可以通过下标来直接访问和修改元素的值。
-
元素顺序:顺序表中元素的顺序是有序的,即元素的插入和删除操作会影响其在顺序表中的位置。
顺序表的优点是随机访问效率高 ,可以快速定位和操作元素。但同时也存在容量限制和插入/删除元素时需要移动数据的缺点。因此,在选择数据结构时,需要根据实际需求来权衡使用顺序表的利弊。
特点
-
随机访问:顺序表中的元素在内存中是连续存储的,因此可以通过下标直接访问元素。这种随机访问的特性使得查找、读取和修改元素的时间复杂度为O(1),即常数时间。相比于链表等其他数据结构,顺序表具有更高的访问效率。
-
快速遍历:由于元素的连续存储,顺序表可以通过下标进行快速遍历。遍历顺序表只需要遍历整个数组,不需要进行指针的跳转操作,因此在需要频繁访问和修改元素的场景下,顺序表的遍历效率较高。
-
固定容量:顺序表在初始化时需要指定最大容量,一旦达到容量限制,就无法再添加新的元素。这使得顺序表的空间利用率较高,且不会因为频繁地申请和释放内存而导致内存碎片问题。
-
插入和删除效率低:由于顺序表的元素在内存中是连续存储的,当需要在中间位置插入或删除元素时,需要移动其他元素,导致时间复杂度为O(n),其中n为元素的个数。因此,在频繁插入和删除元素的场景下,顺序表的效率较低。
-
操作简单:顺序表的操作相对简单,包括插入、删除、查找和遍历等。由于元素的随机访问特性,可以方便地对元素进行各种操作。
综上所述,顺序表具有随机访问和快速遍历的优点,适用于需要频繁访问和修改元素的场景。但由于固定容量和插入/删除效率低的限制,需要根据实际需求来选择合适的数据结构。
顺序表的运算
运算符 -> 也可用于选择结构或联合的成员,
顺序表是一种线性表的存储结构,可以进行一系列基本的运算操作,包括初始化、插入、删除、查找和遍历等。
结构
c
/*顺序表*/
typedef struct
{
DataType data[MAXSIZE];
int length;
}SeqList;
初始化
顺序表的初始化是指创建一个空的顺序表,即分配一定大小的内存空间,并将元素个数设为0。
c
/*顺序表初始化*/
int init(SeqList *L)
{
L->length = 0;
return 0;
}
插入
在顺序表中插入元素可以通过两种方式进行。一种是在指定位置插入元素,需要将插入位置后的元素依次后移,然后将新元素插入到指定位置。另一种是在末尾插入元素,只需要将新元素添加到顺序表的末尾即可。
c
/*插入元素*/
int insert(SeqList *L, int i, DataType x)
{
int j;
/*判断是否满*/
if(full(L))
{
printf("Error[10001],顺序表已满!\n");
return 10001;
}
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("位置i不合法!\n");
return 10002;
}
/*移动元素,向后移动*/
for(j=L->length;j>=i;j--)
{
L->data[j] = L->data[j-1];
}
L->data[j] = x;
L->length++;
return 0; /*ok!*/
}
删除
顺序表中的元素删除操作主要有两种方式。一种是删除指定位置的元素,需要将删除位置后的元素依次前移,然后将最后一个元素删除。另一种是删除指定值的元素,需要先查找到该元素的位置,然后再进行删除操作。
在第n-1个往后挪
c
/*删除元素*/
int delete(SeqList *L, int i, DataType *x)
{
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("Error[10002],位置i不合法!\n");
return 10002;
}
int j;
for (j = i-1; j < L ->length; j++)
{
L->data[j] = L->data[j+1];
}
L->length--;
return 0;
}
遍历
顺序表的遍历是指逐个访问顺序表中的元素。可以使用循环结构,按照下标依次访问顺序表中的元素,或者使用迭代器等方式进行遍历。
c
/*输出顺序表*/
void print(SeqList *L)
{
int i;
if(empty(L))
{
printf("顺序表为空!");
return ;
}
printf("顺序表为:");
for(i=0;i<L->length;i++)
{
printf(" %d ", L->data[i]);
}
printf("\n");
}
通过以上运算,可以实现对顺序表中元素的增删查改等操作,满足不同的业务需求。
顺序表的实现
完整代码
项目结构
css
main.c
SeqList.c
SeqList.h
welcome.h
项目文件
C语言讲义------传值、传引用 - 虎老狮 - 博客园 (cnblogs.com)
SeqList.h
c
/*
SeqList.h 顺序表定义
*/
#define MAXSIZE 1000
typedef int DataType;
/*顺序表*/
typedef struct
{
DataType data[MAXSIZE];
int length;
}SeqList;
/*顺序表初始化*/
int init(SeqList *L);
/*顺序表的长度*/
int length(SeqList *L);
/*顺序表是否满*/
int full(SeqList *L);
/*是否空*/
int empty(SeqList *L);
/*插入元素*/
int insert(SeqList *L, int i, DataType x);
/*删除元素*/
int delete(SeqList *L, int i, DataType *x);
/*输出顺序表*/
void print(SeqList *L);
SeqList.c
c
/*
SeqList.c 顺序表实现
*/
#include "SeqList.h"
/*顺序表初始化*/
int init(SeqList *L)
{
L->length = 0;
return 0;
}
/*顺序表的长度*/
int length(SeqList *L)
{
return L->length;
}
/*顺序表是否满*/
int full(SeqList *L)
{
return (L->length == MAXSIZE)?1:0;
}
/*是否空*/
int empty(SeqList *L)
{
return (L->length == 0)?1:0;
}
/*插入元素*/
int insert(SeqList *L, int i, DataType x)
{
int j;
/*判断是否满*/
if(full(L))
{
printf("Error[10001],顺序表已满!\n");
return 10001;
}
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("位置i不合法!\n");
return 10002;
}
/*移动元素,向后移动*/
for(j=L->length;j>=i;j--)
{
L->data[j] = L->data[j-1];
}
L->data[j] = x;
L->length++;
return 0; /*ok!*/
}
/*删除元素*/
int delete(SeqList *L, int i, DataType *x)
{
/*判断位置i合法性*/
if(i<1 || i>length(L)+1)
{
printf("Error[10002],位置i不合法!\n");
return 10002;
}
int j;
for (j = i-1; j < L ->length; j++)
{
L->data[j] = L->data[j+1];
}
L->length--;
return 0;
}
/*输出顺序表*/
void print(SeqList *L)
{
int i;
if(empty(L))
{
printf("顺序表为空!");
return ;
}
printf("顺序表为:");
for(i=0;i<L->length;i++)
{
printf(" %d ", L->data[i]);
}
printf("\n");
}
welcome.h
c
char welcome[] = "welcome";
main.c
c
#include <stdio.h>
#include "SeqList.h"
#include <string.h>
#include "welcome.h"
int main(int argc, char* argv[])
{
SeqList L;
int cmd;
int i;
int m,n;
DataType x;
for(i=0;i<strlen(welcome);i++)
{
printf("%c",welcome[i]);
for(m=0;m<10000;m++)
for(n=0;n<1000;n++)
{
;
}
}
printf("\n\n\n");
printf("-----------顺序表演示程序----------\n");
do
{
printf("1. 初始化顺序表\n");
printf("2. 插入元素\n");
printf("3. 删除元素\n");
printf("4. 判断顺序表是否为空\n");
printf("5. 判断顺序表是否满\n");
printf("6. 输出顺序表\n");
printf("10. 帮助\n");
printf("0. 退出\n");
printf("请输入您要进行的操作(1~6,0退出):");
scanf("%d", &cmd);
switch(cmd)
{
case 1:
if(!init(&L))
{
printf("顺序表已初始化!\n");
}
break;
case 2:
printf("请输入位置i,插入元素x(i,x):");
scanf("%d,%d",&i,&x);
if(!insert(&L,i,x))
{
printf("元素(%d)已插入位置[%d]\n",x, i);
}
break;
case 3:
printf("请输入位置i,删除元素x(i):");
scanf("%d",&i);
if(!delete(&L,i,x))
{
printf("元素(%d)删除位置[%d]\n",x, i);
}
break;
case 4:
if(!empty(&L))
{
printf("顺序表不为空!\n");
}
else
{
printf("顺序表为空!\n");
}
break;
case 5:
if(full(&L))
{
printf("顺序表已满!\n");
}
else
{
printf("顺序表未满!\n");
}
break;
case 6:
print(&L);
break;
case 10:
printf(" 本程序为顺序表的演示程序,有XXX设计开发,程序完成了。。。。功能!。。。\n");
break;
}
}while(cmd != 0);
return 0;
}
执行结果



小结
顺序表是一种基本的线性表数据结构,它以连续的内存空间存储元素,并通过下标进行访问。以下是顺序表的一些特点和总结:
优点
-
随机访问:由于元素在内存中的连续存储,顺序表支持通过下标直接访问元素,访问效率高,时间复杂度为O(1)。
-
快速遍历:顺序表可以通过下标进行快速遍历,适用于需要频繁访问和修改元素的场景。
-
适合读取操作:由于顺序表的随机访问特性,它适合读取操作频繁的场景,例如按照下标快速访问元素。
缺点
-
固定容量:顺序表在创建时需要指定最大容量,空间利用率高,但容量不可动态调整。
-
插入和删除效率低:在顺序表的中间位置插入或删除元素时,需要移动其他元素,效率较低,时间复杂度为O(n)。
-
不适合频繁插入和删除:由于插入和删除操作需要移动其他元素,顺序表不适合频繁插入和删除操作的场景。
总之,顺序表是一种简单且常见的数据结构,适用于需要频繁访问和修改元素的场景。它具有快速随机访问和遍历的优点,但在插入和删除操作上效率较低。在实际应用中,根据具体需求和操作的频率,可以选择合适的数据结构来提高效率和满足需求。