顺序表是线性表的顺序储存方式,它是指在内存中用地址连续的一块储存空间顺序存放线性表的各元素。一维数组在内存中占用的储存空间就是一组连续的储存区域,因此,用一维数组来表示顺序储存的数据区域再合适不过。
封装
考虑到线性表的运算有插入、删除等,即表的长度是动态可变的,因此,数组的容量需设计得足够大。假设用Data[ MAXSIZE]来表示,其中 MAXSIZE是一个根据实际问题定义的足够大的整数,线性表中的数据从Data[0]开始依次顺序存放。由于当前线性表中的实际元素个数可能未到 MAXSIZE多个,因此需用一个变量Last记录当前线性表中最后一个元素在数组中的位置,即Last起一个指针(实际是数组下标)的作用,始终指向线性表中最后一个元素。表满时Last = MAXSIZE - 1,表空时Last = - 1。
typedef int Position;
typedef int ElementType;
/*为了体现数据组织的整体性,通常将数组Data和变量Last封装成一个结构作为顺序表的类型:*/
typedef struct LNode* PtrToLNode;
struct LNode{
ElementType Data[MAXSIZE];//存储数据,数组下标从0开始
Position Last;//数据的下标,作为索引方便找到Data
};
typedef PtrToLNode List;
/*typedef是取别名,主要是为了方便修改类型,一般刚学c语言的可能看不懂,
这是C语言的入门知识,搞不懂的去百度学习下吧,我就不细讲了*/
线性表的顺序储存示意图
操作集
(1)List MakeEmpty( ):初始化一个新的空线性表;
(2)ElementType FindX( List L,int i):根据指定的位序i,返回L中相应元素X;
(3)Position Find( List L, ElementType X):已知X,返回线性表L中与X相同的第一个元素 的位置;若不存在则返回错误信息;
(4)bool Insert( List L, ElementType,int i):在L的指定位序i前插入一个新元素X;成功则 返回true,否则返回 false;
(5)bool Delete( List L,int i):从L中删除指定位序i的元素;成功则返回true,否则返回 false
(6)int Length( List L):返回线性表L的长度。
1.初始化
首先动态分配表结构所需要的储存空间,然后将表中Last初始为-1,表示表中没有元素。
List MakeEmpty()
{
List L;
L = (List)malloc(sizeof(struct LNode));
L->Last = -1;
return L;
}
2.查找元素
直接通过索引找到对应元素L->Data[i]。
ElementType FindX( List L,int i )
{
if (i<-1 || i>L->Last + 2)
{
printf("位序不合法");
return false;
}
return L->Data[i];
}
3.查找位置
从第一个元素起依次和X比较,直到找到和X相等的元素,并且返回它的下标;如果遍历完顺序表都没找到和X相等的元素,返回错误信息ERROR。
Position Find( List L, ElementType X )
{
Position i;
while (i <= L->Last && L->Data[i] != X)
i++;
if (i > L->Last)
return ERROR; /*如果没找到则返回错误信息*/
return i; /*找到后返回存储位置*/
}
4.插入
先将ai~an顺序向后移动 ,为新元素让出位置;将X置人空出的第i个位序;修改Last指针(相当于修改表长),使之仍指向最后一个元素。
Bool Insert(List L, ElementType X, int i)
{
/*在L的指定位序i前插入一个新元素X;位序i的下标是i-1*/
Position j;
if (L->Last == MAXSIZE - 1) {
/*表空间满,不能插入*/
printf("表满");
return false;
}
if (i<1 || i>L->Last + 2) {
/*检查插入位序是否合法,插入位序是否在1至n+1*/
printf("位序不合法");
return false;
}
for (j = L->Last; j >= i - 1; j--) /*将位序i及以后的元素向后移动*/
L->Data[j + 1] = L->Data[j];
L->Data[i - 1] = X; /*新元素插入第i位,下标为i-1*/
L->Last++; /*新加入元素后记得Last(长度)也要加1*/
return true;
}
5.删除
先将a[i]~a[n]顺序向前移动 ,a[i]元素被a[i+1]元素覆盖;修改Last指针(相当于修改表长)
Bool Delete(List L, int i)
{
/*在L中删除指定位序i元素;该元素数组下标是i-1*/
Position j;
if (i<1 || i>L->Last + 1) {
/*检查删除位序是否合法*/
printf("位序不合法");
return false;
}
for (j = i; j <= L->Last; j++) /*将位序i+1及以后的元素向前移动*/
L->Data[j - 1] = L->Data[j];
L->Last--; /*删除元素后记得Last(长度)要减1*/
return true;
}
完整代码
#include<stdio.h>
#include<stdlib.h>
/*MAXSIZE为顺序表最大长度*/
#define MAXSIZE 100
#define ERROR 0
/*C语言是没有bool类型的,我习惯这样宏定义*/
#define Bool int
#define false 0
#define true 1
/*为了体现数据组织的整体性,通常将数组Data和变量Last封装成一个结构作为顺序表的类型:*/
typedef int Position;
typedef int ElementType;
typedef struct LNode* PtrToLNode;
struct LNode {
ElementType Data[MAXSIZE];//存储数据,数组下标从0开始
Position Last;//数据的下标,作为索引方便找到Data
};
typedef PtrToLNode List;
/*typedef是取别名,主要是为了方便修改类型,一般刚学c语言的可能看不懂,
这是C语言的入门知识,搞不懂的去百度学习下吧,我就不细讲了*/
//初始化
List MakeEmpty( )
{
List L;
L = (List)malloc(sizeof(struct LNode));
L->Last = -1;
return L;
}
//查找元素
ElementType FindX(List L, int i)
{
if (i<-1 || i>L->Last + 2)
{
printf("位序不合法");
return false;
}
return L->Data[i];
}
//查找元素位置
Position Find(List L, ElementType X)
{
Position i = 0;
while (i <= L->Last && L->Data[i] != X)
i++;
if (i > L->Last)
return ERROR; /*如果没找到则返回错误信息*/
return i; /*找到后返回存储位置(下标)*/
}
//插入元素
Bool Insert(List L, ElementType X, int i)
{
/*在L的指定位序i前插入一个新元素X;位序i的下标是i-1*/
Position j;
if (L->Last == MAXSIZE - 1) {
/*表空间满,不能插入*/
printf("表满");
return false;
}
if (i<1 || i>L->Last + 2) {
/*检查插入位序是否合法,插入位序是否在1至n+1*/
printf("位序不合法");
return false;
}
for (j = L->Last; j >= i - 1; j--) /*将位序i及以后的元素向后移动*/
L->Data[j + 1] = L->Data[j];
L->Data[i - 1] = X; /*新元素插入第i位,下标为i-1*/
L->Last++; /*新加入元素后记得Last(长度)也要加1*/
return true;
}
//删除元素
Bool Delete(List L, int i)
{
/*在L中删除指定位序i元素;该元素数组下标是i-1*/
Position j;
if (i<1 || i>L->Last + 1) {
/*检查删除位序是否合法*/
printf("位序不合法");
return false;
}
for (j = i; j <= L->Last; j++) /*将位序i+1及以后的元素向前移动*/
L->Data[j - 1] = L->Data[j];
L->Last--; /*删除元素后记得Last(长度)要减1*/
return true;
}
/*=================================主函数=================================*/
int main()
{
//主函数与测试案例可随意更改
int N, num;
int i;
List L = MakeEmpty();
printf("输入表长,最长为%d\n",MAXSIZE);
scanf("%d", &N);
printf("输入元素\n");
for (i = 0; i < N; i++) {
scanf("%d", &num);
L->Data[i] = num;
L->Last++;
}
printf("查找第3号元素\n");
printf("%d\n" ,FindX(L, 2));
printf("查找5的存储位置\n");
printf("%d\n", Find(L, 5));
printf("插入6在第3号位置\n");
Insert(L, 6, 3);
for (i = 0; i < L->Last+1; i++)
printf("%d ", L->Data[i]);
printf("\n");
printf("删除第3位置的元素\n");
Delete(L, 3);
for (i = 0; i < L->Last + 1; i++)
printf("%d ", L->Data[i]);
return 0;
}
测试案例
这些都是陈越老师数据结构书上的知识,第一次写博客,临近期末了就当作期末复习吧。