在学习数据结构线性表后,其实是有很多不太清楚的地方。为了加深理解和记忆,现在这里整理下基本思路和代码实现:
以下为顺序表的整理,顺序存储方法即把线性表的结点按逻辑次序依次存放在一组地址连续的存储单元里的方法,以数组为载体。
线性表的基本操作包括初始化、销毁、判断表空、查询表长、插入、删除、查询指定位置元素值、查询指定元素位置、输出表。
Status InitList(SeqList *L); //初始化
Status DestroyList(SeqList *L); //销毁
Status IsEmpty(SeqList L, int *empty); //判断是否为空,将结果返回empty,
Status GetLength(SeqList L, int *lenp); //查询表长,将结果返回给lenp
Status InsertList(SeqList *L, int i, ElemType e); //插入操作
Status DeleteList(SeqList *L, int i, ElemType *e); //删除操作
Status GetData(SeqList L, int i, ElemType *e); //查询指定位置元素
Status GetLocation(SeqList L, int *i, ElemType e); //查询指定元素位置
Status PrintList(SeqList L); //输出表中所有元素
定义顺序表的存储结构:
typedef int ElemType; //ElemType的类型可根据实际情况而定,这里假设为int
typedef struct {
ElemType *dataspace; //存储空间的首地址,相当于数组dataspace[0]
int len; //标记存储元素的位置
}SeqList;
注意:表的长度=len+1
1、初始化顺序表:
Status InitList(SeqList *L) { //需要改变线性表的状态,所以传指针
L->dataspace = (ElemType *)malloc(sizeof(ElemType)*MAXSIZE); //分配一个ElemType类型,长度为MAXSIZE的空间(即一个长度为MAXSIZE的数组),将首地址赋给dataspace
if (L->dataspace == NULL) //如果数组首地址空间为NULL,申请空间失败,返回ERROR
return ERROR;
L->len = 0; //顺序表中没有元素
return OK;
}
2、销毁线性表:
Status DestroyList(SeqList *L) {
if (L->dataspace == NULL) //申请空间失败,所以也就进行无法销毁操作,返回ERROR
return ERROR;
free(L->dataspace); //释放首地址的空间(与malloc函数对应)
L->dataspace = NULL; //将dataspace指针置空
L->len = 0; //置0(可做可不做)
return OK;
}
注意释放dataspace的空间后,需要将该指针置空
3、判断是否为空:
Status IsEmpty(SeqList L, int *empty) {
if (L.dataspace == NULL) //判断是否初始化
return ERROR;
*empty = (L.len == 0); //顺序表长度为0时,*empty为1,表示空表
return OK;
}
4、查询表长
Status GetLength(SeqList L, int *lenp) { //查询表长,将结果赋给lenp返回主调函数
if (L.dataspace == NULL)
return ERROR;
*lenp = L.len; //长度值赋给*lenp
return OK;
}
5、插入操作
Status InsertList(SeqList *L, int i, ElemType e) { //在表中第i个位置,插入元素e
int p;
if ( L->dataspace == NULL || (i > L->len + 1 || i < 1)) //没有初始化或者i值不合法,返回ERROR
return ERROR;
for (p = L->len; p >= i-1; p--) //将插入位置后的所有元素依次后移一个单位
L->dataspace[p + 1] = L->dataspace[p];
L->dataspace[i-1] = e; //将元素值e插入到第i个位置(下标为i-1的位置)
L->len++; //表长+1
return OK;
}
插入操作要注意区别插入的物理位置和结点的逻辑顺序保持一致,因为结点是从0位开始的,而物理地址从1开始
6、删除操作
Status DeleteList(SeqList *L, int i, ElemType *e) { //删除表中第i个位置,将值赋给e
int p;
if (L->dataspace == NULL||(i > L->len || i < 1)) //i值不合法或者没有初始化,则返回ERROR
return ERROR;
*e = L->dataspace[i - 1]; //将要删除位置的元素值赋给*e
for (p = i; p <= L->len; p++) //将删除位置后面的所有元素依次前移一个单位
L->dataspace[p-1] = L->dataspace[p];
L->len--; //表长-1
return OK;
}
7、查询指定位置元素值
Status GetData(SeqList L, int i, ElemType *e) { //查询表中第i个位置的元素值,并返回元素值e
if (L.dataspace == NULL || i < 1 || i >= L.len + 1)
return ERROR;
*e = L.dataspace[i - 1]; //因为是顺序存储结构,按序取值
return OK;
}
8、查询指定元素位置
Status GetLocation(SeqList L, int *i, ElemType e) { //查询表中元素值为e的元素,并返回元素位置i
int p = 0;
if (L.dataspace == NULL)
return ERROR;
for (p = 0; p < L.len; p++) { //遍历顺序表
if (L.dataspace[p] == e) { //找到元素后,返回i值
*i = p + 1;
return OK;
}
}
*i = 0; //否则查找失败
return OK;
}
9、输出表中所有元素
Status PrintList(SeqList L) {
int p;
if (L.dataspace == NULL)
return ERROR;
for (p = 0; p < L.len; p++)
printf("%d ", L.dataspace[p]);
printf("\n");
return OK;
}
//
//
下面是源码,三个文件依次为:seqlist.h、seqlist.cpp、main.cpp
#pragma once
#define OK 1
#define ERROR -1
#define MAXSIZE 100
typedef int Status;
typedef int ElemType; //ElemType的类型可根据实际情况而定,这里假设为int
typedef struct {
ElemType *dataspace; //存储空间的首地址,相当于数组dataspace[0]
int len; //标记存储元素的位置
}SeqList;
Status InitList(SeqList *L); //初始化
Status DestroyList(SeqList *L); //销毁
Status IsEmpty(SeqList L, int *empty); //判断是否为空,将结果返回empty,
Status GetLength(SeqList L, int *lenp); //查询表长,将结果返回给lenp
Status InsertList(SeqList *L, int i, ElemType e); //插入操作
Status DeleteList(SeqList *L, int i, ElemType *e); //删除操作
Status GetData(SeqList L, int i, ElemType *e); //查询指定位置元素
Status GetLocation(SeqList L, int *i, ElemType e); //查询指定元素位置
Status PrintList(SeqList L); //输出表中所有元素
/****************************************************************************************/
#include
#include
#include"seqlist.h"
Status InitList(SeqList *L) { //需要改变线性表的状态,所以传指针
L->dataspace = (ElemType *)malloc(sizeof(ElemType)*MAXSIZE); //分配一个ElemType类型,长度为MAXSIZE的空间(即一个长度为MAXSIZE的数组),将首地址赋给dataspace
if (L->dataspace == NULL) //如果数组首地址空间为NULL,申请空间失败,返回ERROR
return ERROR;
L->len = 0; //顺序表中没有元素
return OK;
}
Status DestroyList(SeqList *L) {
if (L->dataspace == NULL) //申请空间失败,所以也就进行无法销毁操作,返回ERROR
return ERROR;
free(L->dataspace); //释放首地址的空间(与malloc函数对应)
L->dataspace = NULL; //将dataspace指针置空
L->len = 0; //置0(可做可不做)
return OK;
}
Status IsEmpty(SeqList L, int *empty) {
if (L.dataspace == NULL) //判断是否初始化
return ERROR;
*empty = (L.len == 0); //顺序表长度为0时,*empty为1,表示空表
return OK;
}
Status GetLength(SeqList L, int *lenp) { //查询表长,将结果赋给lenp返回主调函数
if (L.dataspace == NULL)
return ERROR;
*lenp = L.len; //长度值赋给*lenp
return OK;
}
Status InsertList(SeqList *L, int i, ElemType e) { //在表中第i个位置,插入元素e
int p;
if ( L->dataspace == NULL || (i > L->len + 1 || i < 1)) //没有初始化或者i值不合法,返回ERROR
return ERROR;
for (p = L->len; p >= i-1; p--) //将插入位置后的所有元素依次后移一个单位
L->dataspace[p + 1] = L->dataspace[p];
L->dataspace[i-1] = e; //将元素值e插入到第i个位置(下标为i-1的位置)
L->len++; //表长+1
return OK;
}
Status DeleteList(SeqList *L, int i, ElemType *e) { //删除表中第i个位置,将值赋给e
int p;
if (L->dataspace == NULL||(i > L->len || i < 1)) //i值不合法或者没有初始化,则返回ERROR
return ERROR;
*e = L->dataspace[i - 1]; //将要删除位置的元素值赋给*e
for (p = i; p <= L->len; p++) //将删除位置后面的所有元素依次前移一个单位
L->dataspace[p-1] = L->dataspace[p];
L->len--; //表长-1
return OK;
}
Status GetData(SeqList L, int i, ElemType *e) { //查询表中第i个位置的元素值,并返回元素值e
if (L.dataspace == NULL || i < 1 || i >= L.len + 1)
return ERROR;
*e = L.dataspace[i - 1]; //因为是顺序存储结构,按序取值
return OK;
}
Status GetLocation(SeqList L, int *i, ElemType e) { //查询表中元素值为e的元素,并返回元素位置i
int p = 0;
if (L.dataspace == NULL)
return ERROR;
for (p = 0; p < L.len; p++) { //遍历顺序表
if (L.dataspace[p] == e) { //找到元素后,返回i值
*i = p + 1;
return OK;
}
}
*i = 0; //否则查找失败
return OK;
}
Status PrintList(SeqList L) {
int p;
if (L.dataspace == NULL)
return ERROR;
for (p = 0; p < L.len; p++)
printf("%d ", L.dataspace[p]);
printf("\n");
return OK;
}
/****************************************************************************************/
#include
#include"seqlist.h"
int main() {
int lenp, empty, op, i;
SeqList L;
ElemType e;
do {
printf("====线性表的基本操作演示程序====\n");
printf("==1.初始化创建线性表============\n");
printf("==2.销毁线性表==================\n");
printf("==3.查询线性表的长度============\n");
printf("==4.判断线性表是否为空==========\n");
printf("==5.执行元素插入操作============\n");
printf("==6.执行元素删除操作============\n");
printf("==7.查询指定位置元素============\n");
printf("==8.查询指定元素位置============\n");
printf("==9.依次输出所有的数据元素======\n");
printf("================================\n");
printf("请输入操作指令序号:\n");
scanf_s("%d", &op);
switch (op) {
case 1:
if (InitList(&L)==OK)
printf("初始化线性表成功!\n");
else
printf("初始化失败!\n");
break;
case 2:
if (DestroyList(&L)==OK)
printf("线性表销毁成功!\n");
else
printf("销毁失败!\n");
break;
case 3:
if (GetLength(L, &lenp)==OK)
printf("线性表长度为:%d\n", lenp);
else
printf("查询长度失败!\n");
break;
case 4:
if (IsEmpty(L, &empty) == ERROR)
printf("线性表未被初始化!\n");
else if (empty)
printf("线性表为空!\n");
else
printf("线性表不为空!\n");
break;
case 5:
printf("请输入要插入的元素位置、元素值:\n");
scanf_s("%d %d", &i, &e);
if (InsertList(&L, i, e)==OK)
printf("插入成功!\n");
else
printf("插入失败!\n");
PrintList(L);
break;
case 6:
printf("请输入要删除的元素位置:\n");
scanf_s("%d", &i);
if (DeleteList(&L, i, &e)==OK)
printf("删除成功!\n");
else
printf("删除失败!\n");
PrintList(L);
break;
case 7:
printf("请输入要查询的元素位置:\n");
scanf_s("%d", &i);
if (GetData(L, i, &e)==OK)
printf("查询成功!元素值为:%d\n", e);
else
printf("查询指定位置元素失败!\n");
break;
case 8:
printf("请输入要查询的元素值:\n");
scanf_s("%d", &e);
if (GetLocation(L, &i, e)==OK)
printf("查询成功!元素位置为:%d\n", i);
else
printf("查询指定元素位置失败!\n");
break;
case 9:
if (PrintList(L) == ERROR)
printf("操作失败,线性表未被初始化!\n");
break;
}
printf("\n");
} while (op > 0);
return 0;
}