线性表简述及理解
我们在接触到数据结构之后开始学习到的就是线性表,那么在这两节中我将提供线性表的简单使用和理解,这个过程自己也能够复习一下:
线性表:0个数据元素 或者多个数据元素的有限序列 个数有限 元素之间有顺序
数据元素就是数据的基本单位 处理的时候整体考虑 (不可拆分)
线性表的长度:有限序列的个数就是线性表的长度
首元素只有直接后继没有直接前驱(简单理解: 第一个元素前面没有数据元素 只有后面有元素)尾元素只有直接前驱没有直接后继(简单理解:最后一个元素后面没有数据元素 只有前面有元素)线性表中中间的元素既有直接前驱也有直接后继(简单理解:中间的元素前面有元素,后面也有元素)介绍抽象数据类型: 内容包括数据和操作 (简单理解就是你有什么东西,那这些东西要干什么)只强调有那些操作 不强调具体实现过程、
Data :a1,a2,a3,a4,…,ai-1,ai,ai+1,…,an 数据部分Operation 操作
接下来介绍顺序存储结构:(类似于数组)
1.用一段地址连续的存储空间
2.依次存储线性表中的元素
区分数据长度和线性表的长度:(详细区分在后面)
数据长度:一个固定值 就是数组长度
线性表长度:线性表中已经保存的数据元素的个数 是一个变化量。
简单理解:数据长度相当于铁路长度,线性表相当于火车长度。火车的长度可以改变,那么线性表的长度也能改变,并且长度不能超过数据长度。
线性表的地址计算方法:
地址:存储器中每个单元的编号:address(ai) = address(ai - 1) + n =address(a0) + n * (i-1)
n表示每个元素所占的存储空间
简单理解:如果火车一节车厢长度是单独的铁轨的两倍长,那么你要到下一个车厢,就要走两节铁轨的长度才能到达。那么从上一个地址访问到下一个地址就需要增加车厢的长度。
数据结构所学的线性表和链表是最重要的两个分类
而递归与非递归思想也是最主要的最常用的两个思想
下面是一些线性表功能的源代码:
#include<stdio.h>
#define MAXSIZE 20 /*存储空间初始分配量*/
//元素数据类型,假设为int。
// 方便自己以后修改
typedef int ElemType;
//线性表的结构定义
typedef struct
{
ElemType data[MAXSIZE]; /*数组存储数据元素,最大值为MAXSIZE*/
int length; /*线性表当前的长度*/
}SqList;
void show(SqList *L){
int i;
for(i = 0; i < L->length; i++){
printf("%d ",L->data[i]);
}
printf("\n");
return;
}
void change(SqList *L){
int i;
ElemType e;
printf("请输入要修改数据的位置\n");
scanf("%d",&i);
//如果线性表长度为0,或者是插入位置不再线性表的范围内,则返回错误
if(L->length == 0 || i < 1 || i > L->length)
{
printf("要修改的位置不在线性表的范围内\n");
return;
}
//如果线性表长度不为0,且插入范围在线性表的正确范围,用*e返回线性表第i个数据的值
else
{
printf("要将数据修改为:\n");
scanf("%d",&e);
L->data[i-1] = e;
printf("修改成功\n");
}
return;
}
/**
* 获得线性表的第i个位置的元素
* @SqList L 传入要查询的线性表
* @int i 线性表的第i个位置
* @ElemType *e 元素类型
*/
void search(SqList *L)
{
int i;
printf("请输入要查询数据的位置\n");
scanf("%d",&i);
//如果线性表长度为0,或者是插入位置不再线性表的范围内,则返回错误
if(L->length == 0 || i < 1 || i > L->length)
{
printf("插入位置不在线性表的范围内\n");
return;
}
//如果线性表长度不为0,且插入范围在线性表的正确范围,用*e返回线性表第i个数据的值
else
{
printf("%d位置的数据为%d\n",i, L->data[i-1]);
}
return;
}
void add(SqList *L)
{
ElemType e;
int i;// i 待插入数据下标,e 数据元素
if(L->length == MAXSIZE){//线性表已经满了
printf("线性表已经满了,无法插入\n");
return;
}
printf("请输入待插入的数据和待插入的位置\n");
scanf("%d %d",&e, &i);
//插入的范围不在线性表内部
if(i < 1 || i > L->length + 1){
printf("插入的范围不在线性表内部\n");
return;
}
if(i <= L->length && i >= 1)
{
//把插入位置后面的元素从后面依次往后移动一个单位!
for(int k = L->length-1; k >= i - 1; k--)
{
L->data[k+1] = L->data[k];
}
//在第i个数据(数组中位置为i-1)插入元素
L->data[i-1] = e;
//线性表当前长度增加一位
L->length ++;
printf("插入成功\n");
}
return;
}
void del(SqList *L)
{
int i;
int status;
//如果线性表为空,则返回错误
if(L->length == 0){
printf("线性表为空,无法删除\n");
return;
}
printf("请输入待数据位置\n");
scanf("%d",&i);
//如果删除的位置不在线性表内,则返回错误
if(i < 1 || i > L->length){
printf("删除的位置不在线性表内,无法删除\n");
return;
}
//如果删除的不是线性表最后一个位置的元素,则删除位置后所有的元素前移一步
if(i<L->length)
{
for(int k = i; k<L->length; k++)
{
L->data[k-1] = L->data[k];
}
L->length --;
printf("删除成功\n");
}
return;
}
/**
* 主函数,用于测试对线性表的操作。
*/
int main(int argc, char const *argv[])
{
ElemType myType;
SqList myList = {}; // 空的线性表
int n,i; // n:数据数量
int flag = 1; // 循环判断
int choice;
printf("请输入原始线性表中的元素个数及元素\n");
scanf("%d",&n);
for(i=0;i<n;i++){
scanf("%d",&myList.data[i]);
}
myList.length = n;
while(flag) {
/*主菜单*/
printf("\n------ 线性表数据管理------\n");
printf("1. 增加元素\n");
printf("2. 修改元素\n");
printf("3. 查找元素\n");
printf("4. 删除元素\n");
printf("5. 显示表\n");
printf("6. 退出\n");
printf("请选择(1-6):");
scanf("%d",&choice);
getchar();
switch(choice){
case 1:
add(&myList);
break;
case 2:
change(&myList);
break;
case 3:
search(&myList);
break;
case 4:
del(&myList);
break;
case 5:
show(&myList);
break;
case 6:
flag = 0;
break;
default :
printf("输入有误,请确认后再次输入!!!");
break;
}
}
return 0;
}