目录
一、顺序表的定义
顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素,使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。
二、顺序表的特点
空间连续:顺序表存储数据密度大,空间利用率高,且数据元素连续存放。
随机访问:顺序表可以通过下标直接访问元素,即支持在O(1)时间内找到第i个元素。
存取速度快:顺序表通过下标来直接存储和访问元素,速度较快。
拓展容量不方便:顺序表的空间是连续的,不能拓展容量,当存储的元素个数超过预先分配的空间时,会导致空间浪费。
插入、删除操作不方便:顺序表在插入或删除元素时需要移动大量元素,时间复杂度为O(n)。
存储密度高:顺序表每个节点只存储数据元素本身,相较而言,存储密度较高。
三、顺序表的运算(概述)
插入操作:在顺序表的指定位置插入一个元素。这可以通过将插入位置后的元素依次向后移动来实现。
删除操作:从顺序表中删除指定位置的元素。这可以通过将删除位置后的元素依次向前移动来实现。
查找操作:在顺序表中查找指定元素的位置。可以使用线性搜索或二分搜索等算法来实现。
更新操作:修改顺序表中指定位置的元素的值
四、顺序表的实现
插入操作:
在顺序表中插入一个元素,需要找到插入位置并将该位置及其之后的元素向后移动一位,然后将新元素放在插入位置。如果需要插入的位置超过了顺序表的大小,则需要动态扩容数组。
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("Error[10002],位置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) {
int j;
//判断输入元素的位置是否合法
if(i<1 || i>length(L)+1) {
printf("Error[10002],位置i不合法!\n");
return 10002;
}
x=L->data[i] ;
for(j=i; j<L->length-1; j++)
L->data[j]=L->data[j+1];
L->length--;
return 0;//删除完成
}
输出操作:
使用循环遍历数组并逐个输出元素:可以使用for循环或while循环遍历数组,逐个访问元素并输出它们的值。
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");
}
判空:
判断顺序表的长度是否为0:如果顺序表的的长度为0,则该顺序表为空。
/*是否空*/
int empty(SeqList *L) {
return (L->length == 0)?1:0;
}
五、完整代码
#include <stdio.h>
#include "SeqList.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("请输入删除元素位置:");
scanf("%d,%d",&i,&x);
if(!delete(&L,i,&x))
{
printf("元素已删除!\n");
}
else{
printf("元素删除失败!\n") ;
}
break;
case 4: //判断顺序表是否为空
{
if(empty(&L)){
printf("顺序表为空!\n");
}else{
printf("顺序表不为空!\n");
}
}break;
case 5://判断顺序表是否满
if(full(&L))
{
printf("顺序表已满!\n");
}
else
{
printf("顺序表未满!\n");
}
case 6://输出顺序表
print(&L);
break;
case 10://帮助
printf(" 本程序为顺序表的演示程序,有XXX设计开发,程序完成了。。。。功能!。。。\n");
break;
}
}while(cmd != 0);
return 0;
}
/*
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("Error[10002],位置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) {
int j;
//判断输入元素的位置是否合法
if(i<1 || i>length(L)+1) {
printf("Error[10002],位置i不合法!\n");
return 10002;
}
x=L->data[i] ;
for(j=i; j<L->length-1; 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");
}
六、运行结果
总结
顺序表是一种简单直观的数据结构,适用于需要随机访问元素的场景。但由于其在插入和删除元素时需要移动大量元素,效率较低,因此在需要频繁插入和删除元素的场景中不太适用。