个人主页:
仍有未知等待探索_小项目,洛谷刷题,数据结构-CSDN博客
专题分栏---数据结构:
数据结构_仍有未知等待探索的博客-CSDN博客
目录
一、知识储备
二、引例
三、顺序表
第一步,先创建一个顺序表类型
第二步,定义和初始化顺序表
第三步,顺序表的基本操作
1.插入(增)
2.删
3.取
4.查
5.计算链表长度
四、 完整的顺序表
一、知识储备
我们之前学的高级语言,比如C语言,JAVA语言,讲的是一些语法,顺序结构,选择结构,循环结构,还有怎么通过那三个结构和语法写出代码来解决一些问题。
而现在,数据结构是在研究的是数据的逻辑结构和数据的物理结构以及它们之间的相互关系,并对这种结构定义相适应的运算,设计出相应的算法,并确保经过这些运算以后所得到的新结构仍保持原来的结构类型。
数据结构可以大概分为3大类:线性表,树,图。而这三大类基本上都有顺序存储结构和链式存储结构。而这篇文章主要是关于线性表中的顺序表的顺序存储结构。
二、引例
顺序表的顺序存储结构是指将线性表的所有数据元素,按其逻辑顺序依次存储在一组连续的内存单元中,用这种存储形式存储的线性表成为顺序表。其特点是逻辑关系相邻的两个数据元素在物理位置上也相邻。
学生信息表
学号 姓名 成绩 1 2022123 张三 90 2 2022124 李四 95 3 2022125 王五 85就像上述的学生信息表一样,要是让你的话如何存储这个表格呢?是不是在一个描述人的结构体里面直接存储这些信息,然后定义一个结构体数组来进行存储呢?
struct student { int num;//学号 char name[20];//姓名 int score;//成绩 };
#define MAX 3 struct student s[MAX]; for(int i=0;i<MAX;i++) { scanf("%d",&s[i].num); char name[20]; scanf("%s",name); strcpy(s[i].name,name); scanf("%d",&s[i].score); }
是否会像如上一样储存呢?
三、顺序表
第一步,先创建一个顺序表类型
#define MAX 100 typedef struct { int num; char name[20]; int score; }elemtype; typedef struct LNode { elemtype data[MAX]; int last; }List;
大家应该都知道define定义了一个常量MAX,让其值为100。然后,在接下来中所有出现的100,均用MAX代替,这样要是想修改数字(扩大数组)的话,直接在define中定义上改就行,避免了繁琐的修改数据的步骤。
typedef是一个重命名的关键词,可以给数据类型重新命名。
在顺序表结构体的定义时,把里面的数组也定义为一个结构体类型,把所需要的数据类型全放在里面。
第二步,定义和初始化顺序表
List* ListInit() { List* L; L = (List*)malloc(sizeof(List)); L->last = -1; return L; }
把L->last赋值为-1,当输入数据的时候再让L->last++,这个L->last其实存的是数组中最后一个元素的下标。表长为0 的时候,其值为-1。
第三步,顺序表的基本操作
1.插入(增)
在初始化完的空顺序表中依次添加数据的操作。
要注意顺序表的填入数据要连续存入,不能隔一个存一个。
List* ListInsert(List* L) { int P;//插入的位置,从0开始 //插入的元素 int num, score; char name[20]; scanf("%d%d", &P, &num); scanf("%s", name); scanf("%d", &score); if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面 { printf("坐标非法\n"); } else { for (int i = L->last; i >= P; i--) { L->data[i + 1].num = L->data[i].num; L->data[i + 1].score = L->data[i].score; strcpy(L->data[i + 1].name, L->data[i].name); } L->data[P].num = num; L->data[P].score = score; strcpy(L->data[P].name, name); L->last++; } }
if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面
这条语句就是为了让我们的数据是连续存储的。P<0的时候,坐标非法;P>L->last+1是为了让插入数据与原来的顺序表相连。
2.删
删除,是删除指定位置上的数据。
List* Listdelete(List* L) { int P;//删除位置,从0开始 scanf("%d", &P); if (L->last == -1) { printf("顺序表为空,无法删除\n"); } else { if (P<0 || P>L->last) printf("坐标非法\n"); else { for (int i = P; i < L->last; i++) { L->data[i].num = L->data[i + 1].num; L->data[i].score = L->data[i + 1].score; strcpy(L->data[i].name, L->data[i + 1].name); } L->last--; } } return L; }
3.取
取指定位置上的元素
int ListGet(List* L) { int P;//取指定位置,从0开始 scanf("%d", &P); if (P<0 || P>L->last) { printf("坐标非法\n"); return -1; } else { return P; } }
4.查
查找顺序表中是否有某个元素,找到返回下标,否则返回-1
int ListSearch(List* L) { int X;//查找的数据 scanf("%d", &X); for (int i = 0; i <= L->last; i++) { if (X == L->data[i].num) return i; } return -1; }
5.计算链表长度
通过L->last存的是最后元素的下标来计算。文章来源:https://www.toymoban.com/news/detail-712604.html
int ListLength(List* L) { return L->last + 1; }
四、 完整的顺序表
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define MAX 5
typedef struct
{
int num;
char name[20];
int score;
}elemtype;
typedef struct LNode
{
elemtype data[MAX];
int last;
}List;
List* ListInit();
List* ListInsert(List* L);
List* Listdelete(List* L);
int ListGet(List* L);
int ListSearch(List* L);
int ListLength(List* L);
int main()
{
List* L;
L = ListInit();
int n;//插入数据的个数
scanf("%d", &n);
while (n--)
{
L = ListInsert(L);
if (L->last == MAX - 1)
{
printf("顺序表已满,无法插入数据\n");
break;
}
}
L = Listdelete(L);
int s=ListGet(L);
if (s != -1)
{
printf("%d %s %d\n", L->data[s].num, L->data[s].name, L->data[s].score);
}
int s=ListSearch(L);
if (s != -1)
{
printf("找到了,下标为%d\n", s);
}
else
{
printf("未找到\n");
}
int len=ListLength(L);
printf("%d", len);
return 0;
}
List* ListInit()
{
List* L;
L = (List*)malloc(sizeof(List));
L->last = -1;
return L;
}
List* ListInsert(List* L)
{
int P;//插入的位置
//插入的元素
int num, score;
char name[20];
scanf("%d%d", &P, &num);
scanf("%s", name);
scanf("%d", &score);
if (P<0 || P>L->last+1)//大于L->last+1是因为,数据可以插在顺序表的最后一个元素的后面
{
printf("坐标非法\n");
}
else
{
for (int i = L->last; i >= P; i--)
{
L->data[i + 1].num = L->data[i].num;
L->data[i + 1].score = L->data[i].score;
strcpy(L->data[i + 1].name, L->data[i].name);
}
L->data[P].num = num;
L->data[P].score = score;
strcpy(L->data[P].name, name);
L->last++;
}
return L;
}
List* Listdelete(List* L)
{
int P;//删除位置
scanf("%d", &P);
if (L->last == -1)
{
printf("顺序表为空,无法删除\n");
}
else
{
if (P<0 || P>L->last)
printf("坐标非法\n");
else
{
for (int i = P; i < L->last; i++)
{
L->data[i].num = L->data[i + 1].num;
L->data[i].score = L->data[i + 1].score;
strcpy(L->data[i].name, L->data[i + 1].name);
}
L->last--;
}
}
return L;
}
int ListGet(List* L)
{
int P;//取指定位置
scanf("%d", &P);
if (P<0 || P>L->last)
{
printf("坐标非法\n");
return -1;
}
else
{
return P;
}
}
int ListSearch(List* L)
{
int X;//查找的数据
scanf("%d", &X);
for (int i = 0; i <= L->last; i++)
{
if (X == L->data[i].num)
return i;
}
return -1;
}
int ListLength(List* L)
{
return L->last + 1;
}
谢谢各位的支持!!共勉!文章来源地址https://www.toymoban.com/news/detail-712604.html
到了这里,关于C/C++数据结构---顺序表---线性存储结构的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!