什么是顺序表?
顺序表是线性表的顺序表示,即用一组地址连续的存储单元依次存储线性表的数据元素
顺序表的结构图
顺序表的基本操作
定义状态量
#include <stdlib.h>
#include <stdio.h>
#define OK 1
#define ERROR 0
#define OVERFLOW –2
#define TRUE 1
#define FALSE 0
typedef int Status;
定义顺序表的结构体
#define INSTLISTSIZE 10//初始大小
#define INCRESIZE 2//内存不够时,需要增加的大小
typedef int ElemType;//给int型取别名,以至于以后好维护程序
typedef int ElemType;
typedef struct {
ElemType *elem;//顺序表主体,可以存储int类型的指针
int length;//顺序表的大小
int listsize;//顺序表的容量
}SqList;//顺序表的名字
顺序表的基本操作
//初始化InitList(*L); //构造空线性表L
Status InsitList(SqList *L);
//销毁DestoryList(*L); //销毁线性表L
Status DestoryList(SqList *L);
//清空ClearList(*L); //清空线性表L
Status ClearList(SqList *L);
//判表空ListEmpty(L); //判断线性表是否为空
Status ListEmpty(SqList L);
//求表长Length(L); //求线性表元素个数
Status LengthList(SqList L);
//按位查找GetElem(L,i,*e); //查找位序为i的元素,用e返回
Status GetElem(SqList L,int i,ElemType *e);
//按值查找LocateElem(L,e); //查找元素e,返回第一次出现的位序
Status LocationElem(SqList L,ElemType e);
//求前驱PriorElem(L, cur_e,*pre_e); //用pre_e返回cur_e的前驱
Status PriorElem(SqList L,ElemType cur_e,ElemType *pre_e);
//求后继NextElem(L,cur_e,*next_e);//用next_e返回cur_e的后继
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e);
//插入ListInsert( *L, i, e); //将元素e插入的位置i;
Status ListInsert(SqList *L,int i,ElemType e);
//删除ListDelete(*L, i,*e); //删除位置i的元素,用e返回其值
Status ListDelete(SqList *L,int i,ElemType *e);
//遍历(输出)ListTraverse(L); //遍历访问整个表L
Status ListTraverse(SqList L);
顺序表基本操作的实现
顺序表的初始化
//初始化InitList(*L); //构造空线性表L
Status InsitList(SqList *L){
L->elem = (ElemType*)malloc(INSTLISTSIZE*sizeof(ElemType));
if (!L->elem) {
printf("内存分配失败\n");
return ERROR;
}
L->length = 0;
L->listsize = INSTLISTSIZE;
return OK;
}
顺序表的销毁
//销毁DestoryList(*L); //销毁线性表L
Status DestoryList(SqList *L){
if (L->elem) {
free(L->elem);
}
if (L->elem == NULL) {
printf("销毁成功\n");
}
return OK;
}
顺序表的清空
//清空ClearList(*L); //清空线性表L
Status ClearList(SqList *L){
L->length = 0;
printf("清空成功\n");
return OK;
}
顺序表的判空
//判表空ListEmpty(L); //判断线性表是否为空
Status ListEmpty(SqList L){
if (L.length != 0) {
printf("顺序表不为空\n");
return ERROR;
}
printf("顺序表为空\n");
return OK;
}
顺序表的求表长
//求表长Length(L); //求线性表元素个数
Status LengthList(SqList L){
printf("顺序表长度为%d\n",L.length);
return OK;
}
顺序表的按下标查找
//按位查找GetElem(L,i,*e); //查找位序为i的元素,用e返回
Status GetElem(SqList L,int i,ElemType *e){
//判断i是否合法
if (i < 1 || i > L.length) {
printf("i值不合法\n");
return ERROR;
}
//判空
if (L.length == 0) {
printf("顺序表为空\n");
return ERROR;
}
//查找
*e = L.elem[i - 1];
return OK;
}
顺序表的按值查找
//按值查找LocateElem(L,e); //查找元素e,返回第一次出现的位序
Status LocateElem(SqList L,ElemType e){
for (int i = 0; i < L.length; i++) {
if (L.elem[i] == e) {
printf("该元素的下标为%d\n",i);
return OK;
}
}
printf("查询无果\n");
return ERROR;
}
顺序表的当前节点的前驱节点
//求前驱PriorElem(L, cur_e,*pre_e); //用pre_e返回cur_e的前驱
Status PriorElem(SqList L,ElemType cur_e,ElemType *pre_e){
for (int i = 0; i < L.length; i++) {
if (L.elem[i] == cur_e) {
*pre_e = L.elem[i - 1];
return OK;
}
}
printf("查询无果\n");
return ERROR;
}
顺序表的当前节点的后继节点
//求后继NextElem(L,cur_e,*next_e);//用next_e返回cur_e的后继
Status NextElem(SqList L,ElemType cur_e,ElemType *next_e){
for (int i = 0; i < L.length; i++) {
if (L.elem[i] == cur_e) {
*next_e = L.elem[i + 1];
return OK;
}
}
printf("查询无果\n");
return ERROR;
}
顺序表的插入(重点掌握)
//插入ListInsert( *L, i, e); //将元素e插入的位置i;
Status ListInsert(SqList *L,int i,ElemType e){
ElemType *p, *q; //i的合法值为1<=i<=ListLength_Sq(L)+1
if (i<1 || i>L->length + 1) return ERROR; //i值不合法
if (L->length >= L->listsize) { //当前储存空间已满,增加分配
ElemType *newbase = (ElemType *)realloc(L->elem,
(L->listsize + INCRESIZE) * sizeof(ElemType));
if (!newbase)
return ERROR; //储存分配失败
L->elem = newbase; //新基址
L->listsize += INCRESIZE; //增加存储容量
}
q = &(L->elem[i - 1]); //q为插入位置
for (p = &(L->elem[L->length - 1]);
p >= q; --p) *(p + 1) = *p; //插入位置及之后的元素右移
*q = e; //插入e
++L->length; //表长增1
return OK;
}
顺序表节点的删除
//删除ListDelete(*L, i,*e); //删除位置i的元素,用e返回其值
Status ListDelete(SqList *L,int i,ElemType *e){
//判断i值是否合法
if (i < 1 || i > L->length) {
printf("i值不合法\n");
return ERROR;
}
*e = L->elem[i - 1];
for(int j=i-1;j<L->length;j++){
L->elem[j]=L->elem[j+1];
}
L->length--;
return OK;
}
顺序表的遍历
//遍历(输出)ListTraverse(L); //遍历访问整个表L
Status ListTraverse(SqList L){
//判空
if (L.length == 0) {
printf("顺序表为空\n");
return ERROR;
}
printf("顺序表:");
for (int i = 0; i < L.length; i++) {
printf("\t%d",L.elem[i]);
}
printf("\n");
return OK;
}
测试顺序表
int main(void){
SqList L;//顺序表
ElemType e,pre_e,next_e;//元素e,前驱pre_e,后驱next_e
InsitList(&L);//初始化链表
//插入元素
for (int i = 1; i <= 8; i++) {
ListInsert(&L, i, i);
}
//判空
ListEmpty(L);
//求表长
LengthList(L);
//遍历
ListTraverse(L);
//删除
ListDelete(&L, 3, &e);
printf("删除的元素为%d\n",e);
//求表长
LengthList(L);
//遍历
ListTraverse(L);
//求前驱元素
PriorElem(L, 5, &pre_e);
printf("元素5的前驱%d\n",pre_e);
//求后驱元素
NextElem(L, 5, &next_e);
printf("元素5的后驱%d\n",next_e);
//按下标查找
GetElem(L, 6, &e);
printf("第6个元素%d\n",e);
//按值查找,返回下标
LocationElem(L, 4);
//清空
ClearList(&L);
//求表长
LengthList(L);
//销毁
DestoryList(&L);
}