图片引用了数据结构C语言(严蔚敏)课本,在线性表中顺序表逻辑地址相邻,具有和数组地址之间一样的相邻关系,但是如果线性表采用链式存储时它的逻辑地址是不相邻的,两个节点之间每个元素的Node* next保存下一个节点的逻辑地址,我们今天来说说关于顺序表的那些事。
首先我们来看一下它的基本结构
我们一共创建3个文件两个.cpp文件,一个.h文件
首先创建seqlist.h
#pragma once //预防头文件被重复引用
//定长顺序表
#define SIZE 10
typedef struct SeqList
{
int elem[SIZE];//存放数据的数组
int length;//有效数据个数
}SeqList,*PSeqList;//44
//然后我们定义将要用到的函数
void InitSeqList(PSeqList ps);//初始化顺序表
bool Insert(PSeqList ps,int pos,int val);//插入
bool DeletePos(PSeqList ps,int pos);//删除位置
int Search(PSeqList ps,int key);//查找值
bool DeleteVal(PSeqList ps,int key);//删除值
bool IsEmpty(PSeqList ps);//判断是否为空
//获取有效数据个数
int GetLength(PSeqList ps);
//销毁顺序表
void Destroy(PSeqList ps);
//清空数据
void Clear(PSeqList ps);
void Show(PSeqList ps);
我们的顺序表有存放数据的数组和长度来组成。
我们暂且在头文件中定义这些,下面我们来写写顺序表,顺序表是线性表中的基础,所以相对于代码来说比较好写
我们来写seqlist.cpp
#include<stdio.h>
#include<assert.h>
#include"Seqlist.h"
void InitSeqList(PSeqList ps)
{
ps->length = 0;//初始化时一定要将真实存放的个数置0.
ps->elem;
}
static bool IsFull(PSeqList ps)//判断是否已满
{
return ps->length == SIZE;
}
static bool IsEmpty(PSeqList ps)
{
return ps->length == 0;
}
bool Insert(PSeqList ps,int pos,int val)
{
assert(ps != NULL);
//我们判断插入的位置是否不合法,其中要判断空表
if(pos < 0 || pos >SIZE || IsFull(ps))
{
return false;
}
int i = ps->length-1;
for( ;i >= pos;i--)
{
ps->elem[i+1] = ps->elem[i];
}
ps->elem[pos] = val;
ps->length++;//记得插入了要把有效个数+1
return true;
}
bool DeletePos(PSeqList ps,int pos)
{
assert(ps != NULL);
if(pos < 0 || pos >= ps->length)
{
return false;
}
int i = pos;
for(; i < ps->length;i++)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;//这里位置不见了,有效个数也就少了一位
return true;
}
int Search(PSeqList ps,int key)
{
assert(ps != NULL);
int i = 0;
for(i = 0;i < ps->length;i++)
{
if(ps->elem[i] == key)
{
return i;
}
}
return -1;
}
bool DeleteVal(PSeqList ps,int key)
{
assert(ps != NULL);
//if( Search(ps,key)< 0 || Search(ps,key)>= ps->length)
if(Search(ps,key) == -1 || IsEmpty(ps))
{
return false;
}
int i = Search(ps,key);
for(;i < ps->length;i++)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;我们把值删除了,虽然位置还在,但是没有有效值所以也要记得减1
return true;
}
void SeqListInverse(PSeqList ps)
{
int i = 0;
int n = 0;
int len = ps->length;
int *p = ps->elem;
int *q = &ps->elem[len-1];
while(p < q)
{
int tmp = *p;
*p = *q;
*q = tmp;
p++;
q--;
}
}//这是一个逆置顺序表的操作,跟字符串的逆置很相似
int GetLength(PSeqList ps)
{
return ps->length;
}
void Clear(PSeqList ps)
{
ps->length = 0;
}
void Destroy(PSeqList ps)
{
Clear(ps);//定长顺序表不存在指针,所以不用释放指针
}
void Show(PSeqList ps)
{
int i = 0;
for(i = 0;i < ps->length;i++)
{
printf("%d\n",ps->elem[i]);
}
}
我们最后来测试一下test.cpp
#include<stdio.h>
#include<assert.h>
#include"Seqlist.h"
int main()
{
int i = 0;
SeqList s;
InitSeqList(&s);
for(i = 0;i < 10;i++)
{
Insert(&s,i,i);
}
SeqListInverse(&s);
Show(&s);
//Show(&s);
//Clear(&s);
return 0;
}
这样顺序表就写完了,是不是很好理解呢。