1、概念
2、存储结构
3、数据长度和线性表长度的区别
4、顺序表的操作
初始化
判断表满
判空
输出
插入
查找
删除pos位置的值
删除第一个val的值
返回key结点的前驱
返回key结点的后继
清空数据
销毁顺序表
5、完整代码
6、顺序表的优缺点
顺序表:线性表的顺序存储
存储空间的起始位置:数组elem,他的存储位置就是存储空间的存储位置。
线性表的最大存储容量:数组长度MaxSize
线性表的当前长度:length
#define MAXSIZE 20typedef struct SQList
{int elem[10];//数组int length;//长度
}SQList,*PSQList;
- 数组的长度是存放线性表的存储空间的长度,存储分配后诸葛亮一般是不变化的。但是可以用变成手段实现动态分配内存。
- 线性表的长度是线性表中数据元素的个数。随着线性表插入和删除操作的进行,这个量时是变化的,因此在代码实现时对表进行插入和删除时一定要记得对链表长度leng进行修改。
- 在任意时刻,线性表的长度应该小于等于数组长度。
前言:
本例在实现过程中,数组下标均为从0开始。
void InitSqlist(PSQList ps)
{assert(ps!=NULL);if(ps==NULL){return;}ps->length=0;
}
static bool IsFull(PSQList ps)
{return ps->length ==MAXSIZE; //如果满足,返回为true
}
bool IsEmpty(PSQlist ps)
{assert(ps!=NULL)if(ps==NULL)return flase;//空表return ps->length==0;
}
void Show(PSQlist ps)
{assert(ps!=NULL);if(ps==NULL)return;for(int i=0;ilength;i++){printf("%d",ps->elem[i]);}printf("\n");
}
- 表为空表,返回flase
- 表满,返回flase
- 如果插入位置不合理,返回flase
- 不能在下标<0位置插入
- 不能在>=数组长度(越界)的位置插入。
- 如果线性表的长度大于数组长度,返回flase
- 从最后一个元素开始向前遍历到第pos个位置,分别将他们都向后移动一个位置
- 将要插入的元素填入位置pos处
- 表长+1
bool Insert(PSQList ps, int pos, int val)
{assert(ps!=NULL);if(ps==NULL)//判断参数return flase;if(pos<0||pos>ps->length)//没有等号return flase;/*if(ps->length==MAXSIZE)return flase;*/ //可以调用IsFull函数if(IsFull(ps)return flase;//把数据移到后面for(int i=ps->length-1;i>=pos;i--){ps->lelem[i+1]=ps->elem[i];}//插入数据ps->elem[pos]=val;//有效数据个数+1ps->length++;//这个易忘return true;
}
实现在ps查找第一个key值,找到返回下标,没找到返回-1
int Search(PSQList ps, int key)
{assert(ps != NULL);//判断参数if (ps == NULL){return -1;}for (int i = 0; i < ps->length; i++){if (key == ps->elem[i]){return i;//找到了}}//没找到return -1;
}
- 如果删除位置不合适,返回false
- 不能在下标<0位置插入
- 不能在>=数组长度(越界)的位置插入。
- 从删除位置pos开始遍历到最后一个元素位置,分别将她们都向前移动到pos位置
- 表长-1
bool DelPos(PSQList ps, int pos)
{assert(ps != NULL);if (ps == NULL){return false;}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;
}
结合上面查找和删除第一个pos位置的值的代码。
- 查找到val的位置,对返回值进行判断知否合法,不合法返回flase1
- 调用删除函数
bool DelVal(PSQList ps, int val)
{int i = Search(ps, val);if (i < 0){return false;}return DelPos(ps, i);
}
结合上面查找代码
int GetPrio(PSQList ps, int key)
{int i = Search(ps, key);if (i <= 0)//注意,头没有前驱;{return -1;}return i - 1;
}
与返回前驱相似,结合上面查找代码
int GetNext(PSQList ps, int key)
{int i = Search(ps, key);if (i < 0 || i == ps->length - 1)//注意,尾没有后继{return -1;}return i + 1;
}
void Clear(PSQList ps)
{ps->length = 0;
}
void Destroy(PSQList ps)
{Clear(ps);
}
sqlist.h
typedef struct SQList
{int elem[10];int length;
}SQList,*PSQList;//PSQList ==SQList *//初始化
void InitSqlist(PSQList ps);//插入数据,在ps顺序表的pos位置插入val;
bool Insert(PSQList ps, int pos, int val);//判空
bool IsEmpty(PSQList ps);//在ps查找第一个key值,找到返回下标,没有找到返回-1;
int Search(PSQList ps, int key);//删除pos位置的值
bool DelPos(PSQList ps, int pos);//删除第一个val的值
bool DelVal(PSQList ps, int val);//返回key的前驱下标,如果不存在返回-1;
int GetPrio(PSQList ps, int key);//返回key的后继下标,如果不存在返回-1;
int GetNext(PSQList ps, int key);//输出
void Show(PSQList ps);//清空数据
void Clear(PSQList ps);//销毁整个内存
void Destroy(PSQList ps);
sqlist.cpp
#include "sqlist.h"
#include
#include
//定长顺序表;
//初始化
void InitSqlist(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return;}ps->length = 0;
}
//判满
static bool IsFul(PSQList ps)
{return ps->length == 10;
}
//插入数据,在ps顺序表的pos位置插入val;
bool Insert(PSQList ps, int pos, int val)
{assert(ps != NULL);if (ps == NULL){return false;}if (pos<0 || pos>ps->length ||IsFul(ps)){return false;}//把数据移动到后面for (int i = ps->length - 1; i >= pos; i--){ps->elem[i + 1] = ps->elem[i];}//插入数据ps->elem[pos] = val;//有效数据个数++;ps->length++;return true;
}//判空
bool IsEmpty(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return false;}return ps->length == 0;
}//在ps查找第一个key值,找到返回下标,没有找到返回-1;
int Search(PSQList ps, int key)
{assert(ps != NULL);if (ps == NULL){return -1;}for (int i = 0; i < ps->length; i++){if (key == ps->elem[i]){return i;}}return -1;
}//删除pos位置的值
bool DelPos(PSQList ps, int pos)
{assert(ps != NULL);if (ps == NULL){return false;}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;
}//删除第一个val的值
bool DelVal(PSQList ps, int val)
{int i = Search(ps, val);if (i < 0){return false;}return DelPos(ps, i);
}//返回key的前驱下标,如果不存在返回-1;
int GetPrio(PSQList ps, int key)
{int i = Search(ps, key);if (i <= 0)//注意,头没有前驱;{return -1;}return i - 1;
}//返回key的后继下标,如果不存在返回-1;
int GetNext(PSQList ps, int key)
{int i = Search(ps, key);if (i < 0 || i == ps->length - 1)//注意,尾没有后继{return -1;}return i + 1;
}//输出
void Show(PSQList ps)
{assert(ps != NULL);if (ps == NULL){return;}for (int i = 0; i < ps->length ; i++){printf("%d ", ps->elem[i]);}printf("\n");
}//清空数据
void Clear(PSQList ps)
{ps->length = 0;
}//销毁整个内存
void Destroy(PSQList ps)
{Clear(ps);
}
test.cpp //main函数
#include
#include
//#include "sqlist.h"int main()
{SQList sq;printf("%d\n", sizeof(sq));InitSqlist(&sq);//测试插入数据//Insert(&sq, 0, 100);for (int i = -1; i < 20; i++)//循环保证测试的全面性{Insert(&sq, i, i);}//输出Show(&sq);//查找1int i = Search(&sq, 9);if (i >= 0){printf("该值位于%d号下标\n", i);}else{printf("没有找到该值!\n");}//查找2,循环查找,推荐这种测试int index;for (int i = -1; i < 20; i++){index = Search(&sq, i);if (index >= 0){printf("该值位于%d号下标\n", i);}else{printf("没有找到该值!\n");}}//删除DelPos(&sq, 5);//删除DelVal(&sq, 1);Show(&sq);return 0;
}
- 无需为表示表中元素之间的逻辑关系而增加额外的存储空间
- 可以快速地存储表中任一位置的元素
- 插入和删除操作需要移动大量元素
- 当线性表长度变化较大时,难以确定存储空间的容量
- 造成存储空间”碎片“