1、 顺序表是在计算机内存中以数组的形式保存的线性表,是指用一组地址连续的存储单元依次存储数据元素的线性结构。线性表采用顺序存储的方式存储就称之为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。其物理地址相邻,逻辑地址也相邻
2、顺序表的特点:(1)简单;(2)支持随机访问(下标);(3)查找快;(4)缺点:插入和删除慢(但尾删和尾插为O(1))
3、顺序表的存储结构
数据元素在计算机有两种不同的表示方法:顺序映像和非顺序映像;所以得到两种不同的存储结构:顺序存储结构和链式存储结构。而在这里我们的顺序表的存储结构是顺序存储结构。然后我们这样分析,从物理实际分析和逻辑分析它的存储情况,由它的特性是以数组的形式保存的,所以得出在物理上它是连续的,在逻辑上它也是连续的。
定长顺序表的结构:
这是顺序表的定长顺序表,我们定义一个结构体:
typedef struct SeqList
{
int elem[SIZE]; //存放数据的数组
int length; //有效数据的个数
}SeqList,*PSeqList;
4、顺序表的插入:
(1)判断插入位置是否合理;
(2)判断线性表的长度大于等于数组长度;
(3)从最后一个元素开始遍历到第i个位置,分别将它们都向后移动一个位置;
(4)将插入的元素插入位置i处;
(5)表长+1;
//往plist的pos位置插入数据val
bool Insert(PSeqList plist,int pos,int val)
{
assert(plist != NULL);
if(pos<0 || pos>plist->length || plist->length==SIZE)
{
return false;
}
//移动pos后面的数据
//从最后一个元素开始遍历到第i个位置,分别将他们都后移一个位置
for(int i=plist->length-1;i>=pos;i--)
{
plist->elem[i+1] = plist->elem[i];
}
//插入新数据
plist->elem[pos] = val;
//更新有效数据个数
plist->length++;
return true;
}
5、顺序表的删除:
(1)判断删除位置是否合理;
(2)取出删除值;
(3)从删除元素位置开始遍历到最后一个元素位置,分别将它们都向前移动一个位置;
(4)表长-1。
//删除位置值
//rtval:输出参数,保存删除成功的数据
bool DeletePos(PSeqList plist,int pos,int *rtval)
{
assert(plist != NULL);
if(pos<0 || pos>=plist->length)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->elem[pos];
}
//移动数据
for(int i=pos;i<plist->length-1;i++)
{
plist->elem[i] = plist->elem[i+1];
}
plist->length--;
return true;
}
6、插入和删除的时间复杂度分析:
最好情况:
元素要插入到最后一个位置或者删除最后一个元素,时间复杂度为O(1)
最坏情况:
元素要插入到第i个位置或者删除第i个元素,需要移动n-i个元素,为(n-1)/2,时间复杂度为O(n).
7、实现代码:
seqlist.h:
//定长顺序表
#pragma once
#include <stdbool.h>
#define SIZE 10
typedef struct SeqList
{
int elem[SIZE];//保存数据
int length;//有效数据个数
}SeqList;
typedef SeqList *PSeqList;
//初始化函数
void InitSeqList(PSeqList plist);//PSeqList == SeqList*
//往plist的pos位置插入数据val
bool Insert(PSeqList plist,int pos,int val);
//打印
void Show(PSeqList plist);
//判空
bool IsEmpty(PSeqList plist);
//查找,找到了返回下标,没有找到返回-1
int Search(PSeqList plist,int key);
//删除
bool DeleteVal(PSeqList plist,int key);
//删除位置值
//rtval:输出参数,保存删除成功的数据
bool DeletePos(PSeqList plist,int pos,int *rtval);
//获取pos下标存储的数据
bool GetVal(PSeqList plist,int pos,int *rtval);
//修改pos下标的数据
bool SetVal(PSeqList plist,int pos,int newval);
//获取val的前趋值
bool GetPriVal(PSeqList plist,int key,int *rtval);
//获取val的后继值
bool GetNextVal(PSeqList plist,int key,int *rtval);
//长度,即有效数据个数
int GetLength(PSeqList plist);
//清除所有数据
void Clear(PSeqList plist);
//销毁
void Destroy(PSeqList plist);
seqlist.c:
#include "seqlist.h"
#include <stdio.h>
#include <assert.h>
//初始化函数
void InitSeqList(PSeqList plist)//PSeqList == SeqList*
{
assert(plist != NULL);
plist->length = 0;//当前无有效数据
}
//往plist的pos位置插入数据val
bool Insert(PSeqList plist,int pos,int val)
{
assert(plist != NULL);
if(pos<0 || pos>plist->length || plist->length==SIZE)
{
return false;
}
//移动pos后面的数据
for(int i=plist->length-1;i>=pos;i--)
{
plist->elem[i+1] = plist->elem[i];
}
//插入新数据
plist->elem[pos] = val;
//更新有效数据个数
plist->length++;
return true;
}
//打印
void Show(PSeqList plist)
{
assert(plist != NULL);
for(int i=0;i<plist->length;i++)
{
printf("%d ",plist->elem[i]);
}
printf("\n");
}
//判空
bool IsEmpty(PSeqList plist)
{
return plist->length == 0;
}
static bool IsFull(PSeqList plist)
{
return plist->length == SIZE;
}
//
//查找,找到了返回下标,没有找到返回-1
int Search(PSeqList plist,int key)
{
assert(plist != NULL);
for(int i=0;i<plist->length;i++)
{
if(plist->elem[i] == key)
{
return i;
}
}
return -1;
}
//删除
bool DeleteVal(PSeqList plist,int key)
{
int i = Search(plist,key);
if(i == -1)
{
return false;
}
return DeletePos(plist,i,NULL);
}
//删除位置值
//rtval:输出参数,保存删除成功的数据
bool DeletePos(PSeqList plist,int pos,int *rtval)
{
assert(plist != NULL);
if(pos<0 || pos>=plist->length)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->elem[pos];
}
//移动数据
for(int i=pos;i<plist->length-1;i++)
{
plist->elem[i] = plist->elem[i+1];
}
plist->length--;
return true;
}
//获取pos下标存储的数据
bool GetVal(PSeqList plist,int pos,int *rtval)
{
if(pos<0 || pos>=plist->length)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->elem[pos];
}
return true;
}
//修改pos下标的数据
bool SetVal(PSeqList plist,int pos,int newval)
{
if(pos<0 || pos>=plist->length)
{
return false;
}
plist->elem[pos] = newval;
return true;
}
//获取val的前趋值
bool GetPriVal(PSeqList plist,int key,int *rtval)
{
int i = Search(plist,key);
if(i <= 0)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->elem[i-1];
}
return true;
}
//获取val的后继值
bool GetNextVal(PSeqList plist,int key,int *rtval)
{
assert(plist!=NULL);
if(plist==NULL)
{
return false;
}
int i = Search(plist,key);
if(i<0 || i >= plist->length-1)
{
return false;
}
if(rtval != NULL)
{
*rtval = plist->elem[i+1];
}
return true;
})
//长度,即有效数据个数
int GetLength(PSeqList plist)
{
return plist->length;
}
//清除所有数据
void Clear(PSeqList plist)
{
plist->length = 0;
}
//销毁
void Destroy(PSeqList plist)
{
Clear(plist);
}
main.c:
#include <stdio.h>
#include "seqlist.h"
//plistA = plistA U plistB
void Union(PSeqList plistA,PSeqList plistB);
int main()
{
SeqList seq;
InitSeqList(&seq);
for(int i=0;i<20;i++)
{
Insert(&seq,i,i);
}
DeleteVal(&seq,5);
Show(&seq);
Insert(&seq,3,30);
Show(&seq);
Clear(&seq);
Show(&seq);
return 0;
}