在计算机中主要有两种基本的数据结构来存放线性表:顺序表以及链表。其中链表又可以分为单链表,双向链表,单循环链表,双向循环链表,静态链表等。这些都是后话,我们首先对顺序表进行分析。作为数据结构最入门的存储结构,它是很有意义的。
- 顺序表
1.顺序表的结构
在编写顺序表所实现的相关函数之前,我们先要确定顺序表的结构。那么什么是顺序表呢?
定义: 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。
根据以上的定义,我们了解到顺序表具有以下特点:
1.在内存中连续。
2.将数据以数组形式保存。
根据以上特点,我们来对顺序表的结构进行一个定义。
#define MAXSIZE 100
typedef struct SeqList
{
int elem[MAXSIZE]; //创建SIZE大小的数组,用于保存数据。
int length; //用来表示顺序表中有效数据的个数。
//int last; //记录顺序表中最后一个有效数据的下标,空表置-1
}SeqList,*PSeqList;
由于顺序表的数据主题是一个数组,所以访问的时候必定需要用到下标。而获取当前最后一个元素的下标是极为重要的,这里定义了length就可以轻松的达到目的。同理我们也可以直接记录最后一个有效数据的下标,即被注释掉的那行代码,也能达到目的。不过这样写还要额外写一个获取数组长度的函数,略显麻烦。所以取length是非常好的选择。
2.顺序表的各功能实现
(1)初始化:此处需要对参数进行判断,看是否为空。
void InitSeqList(PSeqList ps)
{
assert (ps != NULL);
if ( ps == NULL )
{
return;
}
ps->length = 0;
}
(2)插入:
顺序表能够插入数据的前提条件是:1.插入的位置合法。如pos<0或者pos>length.
2.该顺序表没有满。
所以在编写插入函数之前需要先写一个内部函数,用于判断顺序表是否满。
static bool IsFull (PSeqList ps)
{
return ps->length == SIZE;
}
然后写插入函数。
bool Insert(PSeqList ps,int pos,int val)
{
if (pos < 0 || pos > ps->length || IsFull(ps)) //判断
{
return false;
}
for (int i = ps->length-1; pos <= i ; i--)
{
ps->elem[i+1] = ps->elem[i]; //如果可以插入数据,那么进行判断,进行相应的移位操作
}
ps->elem[pos] = val;
ps->length++;
return true;
}
需要注意的是插入时,数据遍历是从后向前
(3)查找。成功返回下标,失败返回-1.
只需要简单的遍历即可。
int Search(PSeqList ps,int key)
{
for (int i = 0; i < ps->length; i++)
{
if (key == ps->elem[i])
{
return i;
}
}
return -1;
}
(4)删除指定位置的数字
删除和插入非常相似。先对pos的合法性进行判断(此处并不需要判断是否为空),然后将pos后的数值全部向前移一位,最后length--完成删除。
bool DeletePos(PSeqList ps,int pos)
{
if(pos<0 || pos>=ps->length)
{
return false;
}
for(int i=pos;i<ps->length-1;i++)
{
ps->elem[i] = ps->elem[i+1];
}
ps->length--;
return true;
}
删除数据遍历时,是从前向后。
(5)按值删除
将搜索和按位置删除结合,搜索到key对应的位置:如果没有找到Search函数将返回-1,导致DeletePos函数返回false,该删除值函数也返回false。
如果成功找到,将对应位置上的值进行删除。
不过该函数的局限性是:如果顺序表中有相同的数字,在对这个数字进行删除的时候只能删掉从elem[0]开始往右数的第一个值。
所以为了确保删除可以将该函数循环length次。
bool DeleteVal(PSeqList ps,int key) //删除值
{
return DeletePos(ps,Search(ps,key));
}
(6)获取长度
获取当前length即可。
int GetLength(PSeqList ps)
{
return ps->length;
}
(7)判空
bool IsEmpty(PSeqList ps)
{
return ps->length == 0;
}
(8)清空数据
void Clear(PSeqList ps)
{
ps->length = 0;
}