文章目录
前言
- 什么是
抽象数据类型
?
抽象数据类型(Abstract Data Type,简称ADT),具有类似行为的特定数据结构的数学模型;抽象数据类型包括数据元素
、数据元素之间的关系
以及对数据元素的一些操作
,即带有一些操作的数据对象的集合;而在C语言中,利用结构体(struct)来表示数据结构。
顺序表ADT实现
对表的操作( 所有操作前提是顺序表存在)
- CreateList():创建顺序表;
/*创建顺序表时使用malloc函数可以为表在堆中动态分配空间
(malloc函数可以使用也可以不用)*/
//创建表
SeqList *CreateList()
{
SeqList *seqList;
int length,i;
printf("请输入顺序表的长度:");
scanf("%d",&length);
if(length > MAX_SIZE)
{
printf("输入不合法\n");
}
else
{
seqList = (SeqList *)malloc(sizeof(SeqList));
seqList->last = length;
for(i = 0; i < length; i++)
{
scanf("%d",&seqList->elem[i]);
}
printf("创建成功!\n");
return seqList;
}
}
- PrintList(SeqList *L):打印顺序表;
//打印表
void PrintList(SeqList *L)
{
int i;
if(IsEmpty(L))
{
printf("顺序表为空!\n");
}
else
{
printf("输出顺序表:\n");
for(i = 0; i < L->last; i++)
{
printf("%d ",L->elem[i]);
}
printf("\n");
}
}
- DestroyList(SeqList *L):销毁顺序表,即删除顺序表;
/* 销毁表时使用free函数清空顺序表在堆中的空间,并需要将指针置空*/
//删除表
void DestroyList(SeqList *L)
{
free(L);
printf("删除成功!\n");
}
- ClearList(SeqList *L):清空顺序表;
/* 清空顺序表即将顺序表的长度置为0,线性表规定长度为0表示空表*/
//置空表
void ClearList(SeqList *L)
{
L->last = 0;
printf("置空完成!\n");
}
对表中元素的操作(操作的前提是顺序表不为空)
- Locate(SeqList *L, int x):定位元素,输出元素在顺序表中的位置;
//定位元素
void Locate(SeqList *L, int x)
{
int i;
for(i = 0; i < L->last; i++)
{
if(L->elem[i] == x)
break;
}
if(i == L->last)
{
printf("未找到元素!\n");
}
else
{
printf("查找结果:%d\n",i+1);
}
}
- GetData(SeqList *L, int i):查找元素,输出指定位置的元素;
//查找元素
void GetData(SeqList *L, int i)
{
if(i >= L->last || i <= 0)
{
printf("查找位置不合法!\n");
}
else
{
printf("查找结果:%d\n",L->elem[i-1]);
}
}
- InsList(SeqList *L, int i, int x):插入元素,插入元素到指定位置;
//插入元素
void InsList(SeqList *L, int i, int x)
{
if(L->last+1 > MAX_SIZE)
{
printf("无法插入元素!\n");
}
else
{
if(i > L->last+1)
{
printf("插入位置错误,无法插入!!\n");
}
else
{
int j;
for(j = L->last; j >= i; j-- )
{
L->elem[j] = L->elem[j-1];
}
L->elem[i-1] = x;
L->last++;
printf("插入成功!\n");
}
}
}
- DelList(SeqList *L, int i):删除指定位置元素;
//删除指定位置元素
void DelList(SeqList *L, int i)
{
if(i >= L->last || i <= 0)
{
printf("删除位置不合法!\n");
}
else
{
for(; i < L->last; i++)
{
L->elem[i - 1] = L->elem[i];
}
L->last--;
printf("删除成功!\n");
}
}
- DelData(SeqList *L, int x):删除指定元素;
//删除指定元素
void DelData(SeqList *L, int x)
{
int i;
for(i = 0; i < L->last; i++)
{
if(L->elem[i] == x)
break;
}
if(i == L->last)
{
printf("未找到删除的元素!\n");
}
else
{
for(i ; i < L->last-1; i++)
{
L->elem[i] = L->elem[i+1];
}
L->last--;
printf("删除成功!\n");
}
}
顺序表的存储结构
顺序表特点:物理存储结构上连续,逻辑结构上相邻。
顺序表的数据结构:
typedef struct
{
//顺序表数据结构
int elem[MAX_SIZE];
int last;
}SeqList;
//可以根据需要定义顺序表中元素的类型
顺序表插入操作实现
不论元素插入到什么位置,插入点后的元素需要后移。
如何判断顺序表是否存在
定义一个结构体指针,初始状态结构体指针指向为NULL,即为空指针;使用malloc函数为顺序表分配空间,此时结构体指针指向的时堆中动态分配的空间;通过判断结构体指针是否为空来说明顺序表是否存在,销毁顺序表时,调用free函数清空堆中的空间,同时将结构体指针指向空。(关于C语言空指针深入了解)
顺序表中指针传递问题
#include<stdio.h>
void test(int *p)
{
p = NULL;
}
int main()
{
int *p;
test(p);
if(p == NULL)
{
printf("这是空指针!\n");
}
else
{
printf("这是野指针!\n");
}
return 0;
}
//结果输出为野指针
在代码中首先在主函数中定义了一个指针,然后我们调用函数将指针传递过去,在子函数中使用p= NULL(目的将指针设为空指针),但是主函数中的指针却并没有指向NULL(C语言指针传递问题)
原因:传递指针,函数会先复制一个指针,两个指针指向同一个地址,虽然子函数的指向改变了,但是并不会影响到主函数中的指针。
全部代码
GitHub地址:Sequence.cpp