您现在的位置是:首页 >学无止境 >【数据结构与算法】二、线性表的顺序表示【硬核】网站首页学无止境

【数据结构与算法】二、线性表的顺序表示【硬核】

韩飞雨 2023-06-13 20:00:02
简介【数据结构与算法】二、线性表的顺序表示【硬核】

二、线性表

2.1 线性表的定义和特点

在这里插入图片描述

2.2 线性表的顺序表示和实现

图书表的顺序存储结构类型定义:
在这里插入图片描述

#define OK	1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define MAXSIZE  10000 //能够存储的最大图书数量

//1、图书表的顺序存储结构类型定义
//1.1、图书的存储结构
typedef struct{
	char isbn[20];//图书的isbn编号
	char name[50];//图书的名称
	double price;//图书的价格
}Book;
typedef Book ElemType;//元素数据的类型
//1.2、图书表的顺序存储结构
typedef struct{
	ElemType* books;//存储图书数组结构的基地址
	int length;//当前有多少本图书
}BookList;

2.3 类C语言有关操作补充

在调用函数的过程中,当形参为引用类型时,实参和形参占用了相同的空间
在这里插入图片描述

2.4 线性表基本操作的实现

2.4.1 线性表的基本操作:

在这里插入图片描述

2.4.2 线性表L的初始化

在这里插入图片描述

// 顺序表的存储结构
typedef struct {
	ElemType* elems;//存储基本元素的数组基地址
	int length;//当前基本元素的个数
}SqList;
typedef int Statu;
//1、顺序表L的初始化
Statu initSqList(SqList &L) {
	L.elems = new ElemType[MAXSIZE];//为存储数据的数组开辟空间
	if (!L.elems) exit(OVERFLOW);//空间开辟失败
	L.length = 0;//空表长度置为0
	return OK;
}

2.4.3 销毁和清空线性表L

在这里插入图片描述

//2、销毁和清空线性表L
//2.1 销毁顺序表L
void destroySqList(SqList &L) {
	if (L.elems) delete L.elems;
	L.length = 0;
}
//2.2 清空线性表L
void clearSqList(SqList &L) {
	L.length = 0;
}

2.4.4 求线性表L的长度以及判断线性表L是否为空

在这里插入图片描述

//3、求线性表L的长度以及判断线性表L是否为空
//3.1 求线性表L的长度
int getLength(SqList L) {
	return L.length;
}
//3.2 判断线性表L是否为空
Statu isEmpty(SqList L) {
	if (L.length == 0) return TRUE;
	return FALSE;
}

2.4.5 顺序表的取值(根据位置i获取相应位置数据元素的内容)

在这里插入图片描述

//4、顺序表的取值(获取第i个位置数据元素的内容)
Statu getElem(int i, SqList L,ElemType &e) {
	if (i<1 || i>L.length) return ERROR;//数组越界
	e=L.elems[i - 1];
	return OK;
}

2.4.6 顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)

在这里插入图片描述

//5、判断两个数据元素是否相等
Statu isEqual(ElemType a, ElemType b) {
	if (strcmp(a.isbn,b.isbn)==0) return TRUE;
	return FALSE;
}
//6、顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)
int LocateElem(ElemType e, SqList L) {
	for (int i = 0; i < L.length; i++) {
		if (isEqual(L.elems[i],e)) return i+1;
	}
	return 0;
}

顺序表的查找算法分析

在这里插入图片描述

2.4.7 顺序表的插入(在第i个位置插入指定的元素)

在这里插入图片描述

Statu insertSqList(SqList &L, int i,ElemType e) {
	if (i<1 || i>L.length + 1) return ERROR;//插入位置不合法
	if (L.length == MAXSIZE) return ERROR;//元素已满,无法插入
	for (int j = L.length-1; j >=i-1; j--) {
		L.elems[j+1] = L.elems[j];
	}
	L.elems[i - 1] = e;
	L.length++;
	return OK;
}

2.4.8 顺序表的删除(删除第i个位置的元素)

在这里插入图片描述

Statu deleteSqList(SqList& L, int i) {
	if (i<1 || i>L.length) return ERROR;//删除位置不合法
	for (int j = i; j < L.length; j++) {
		L.elems[j - 1] = L.elems[j];
	}
	L.length--;
	return OK;
}

2.5 顺序表(线性表的顺序存储结构)的特点

  • (1)利用数据元素的存储位置表示线性表中相邻数据元素之间的前后关系,即线性表的逻辑结构与存储结构一致

  • (2)在访问线性表时,可以快速地计算出任何一个数据元素的存储地址。因此可以粗略地认为,访问每个元素所花时间相等

  • 这种存储元素的方法被称为随机存取法
    在这里插入图片描述

2.6 C++实现代码

main.cpp

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include"Sqlist.h"


int main() {
	test();
	return 0;
}

Sqlist.h

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define OK	1
#define ERROR 0
#define TRUE 1
#define FALSE 0
#define OVERFLOW -1
#define MAXSIZE  10000 //能够存储的最大图书数量

//1、图书表的顺序存储结构类型定义
//1.1、图书的存储结构
typedef struct{
	char isbn[20];//图书的isbn编号
	char name[50];//图书的名称
	double price;//图书的价格
}Book;
typedef Book ElemType;//元素数据的类型
//1.2、图书表的顺序存储结构
typedef struct{
	ElemType* books;//存储图书数组结构的基地址
	int length;//当前有多少本图书
}BookList;

// 顺序表的存储结构
typedef struct {
	ElemType* elems;//存储基本元素的数组基地址
	int length;//当前基本元素的个数
}SqList;
typedef int Statu;

//函数声明===========================================
//2、顺序表L的初始化
Statu initSqList(SqList &L);
//3、销毁线性表L
void destroySqList(SqList &L);
//4、清空线性表L
void clearSqList(SqList& L);
//5、求线性表L的长度
int getLength(SqList L);
//6、判断线性表L是否为空
Statu isEmpty(SqList L);
//7、顺序表的取值(根据位置i获取相应位置数据元素的内容)
Statu getElem(int i, SqList L, ElemType& e);
//8、顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)
//8.1 //判断两本图书是否相等
Statu isEqual(ElemType a, ElemType b);
//8.2 顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)
int LocateElem(ElemType e, SqList L);
//9、顺序表的插入(在第i个位置插入指定的元素)
Statu insertSqList(SqList& L, int i, ElemType e);
//10、顺序表的删除(删除第i个位置的元素)
Statu deleteSqList(SqList& L, int i);
//11、打印单个元素
void displayElem(ElemType e);
//12、打印整个线性表
void displaySqList(SqList L);
//13、从txt文件中读取数据元素数据
Statu readDataFromTxt(SqList& L, const char* filename);

//================================================

//2、顺序表L的初始化
Statu initSqList(SqList& L) {
	L.elems = new ElemType[MAXSIZE];//为存储数据的数组开辟空间
	if (!L.elems) exit(OVERFLOW);//空间开辟失败
	L.length = 0;//空表长度置为0
	return OK;
}
//3、销毁线性表L
void destroySqList(SqList& L) {
	if (L.elems) delete L.elems;
	L.length = 0;
}
//4、清空线性表L
void clearSqList(SqList& L) {
	L.length = 0;
}
//5、求线性表L的长度
int getLength(SqList L) {
	return L.length;
}
//6、判断线性表L是否为空
Statu isEmpty(SqList L) {
	if (L.length == 0) return TRUE;
	return FALSE;
}
//7、顺序表的取值(根据位置i获取相应位置数据元素的内容)
Statu getElem(int i, SqList L,ElemType &e) {
	if (i<1 || i>L.length) return ERROR;//数组越界
	e=L.elems[i - 1];
	return OK;
}

//8、顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)
//8.1 判断两本图书是否相等
Statu isEqual(ElemType a, ElemType b) {
	if (strcmp(a.isbn,b.isbn)==0) return TRUE;
	return FALSE;
}
//8.2 顺序表的查找(在线性表L中查找与指定值e相同的数据元素的位置)
int LocateElem(ElemType e, SqList L) {
	for (int i = 0; i < L.length; i++) {
		if (isEqual(L.elems[i], e)) return i + 1;
	}
	return 0;
}
//9、顺序表的插入(在第i个位置插入指定的元素)
Statu insertSqList(SqList &L, int i,ElemType e) {
	if (i<1 || i>L.length + 1) return ERROR;//插入位置不合法
	if (L.length == MAXSIZE) return ERROR;//元素已满,无法插入
	for (int j = L.length-1; j >=i-1; j--) {
		L.elems[j+1] = L.elems[j];
	}
	L.elems[i - 1] = e;
	L.length++;
	return OK;
}
//10、顺序表的删除(删除第i个位置的元素)
Statu deleteSqList(SqList& L, int i) {
	if (i<1 || i>L.length) return ERROR;//删除位置不合法
	for (int j = i; j < L.length; j++) {
		L.elems[j - 1] = L.elems[j];
	}
	L.length--;
	return OK;
}
//11、打印单个元素
void displayElem(ElemType e) {
	printf("isbn编号是:%s
", e.isbn);
	printf("图书的名称是:%s
", e.name);
	printf("图书的价格是:%lf
", e.price);
}
//12、打印整个线性表
void displaySqList(SqList L) {
	for (int i = 0; i < L.length; i++) {
		displayElem(L.elems[i]);
	}
}
//13、从txt文件中读取数据元素数据
Statu readDataFromTxt(SqList &L, const char* filename) {
	FILE* file = freopen(filename, "r", stdin);
	if (!file) {
		printf("文件读取失败
");
		return ERROR;
	}
	ElemType e;
	int i = 0;
	while (scanf("%s%s%lf", e.isbn, e.name, &e.price)!=EOF&&i<MAXSIZE) {
		L.elems[i++] = e;
		L.length++;
	}
	return OK;
}
//14、测试函数
void test() {
	SqList L;//定义一个线性表
	initSqList(L);//初始化线性表
	//判断线性表是否为空
	if (isEmpty(L)) printf("线性表是空的
");
	else{
		printf("线性表的长度是: %d
", L.length);
	}
	printf("======1、从文件中读取图书表数据========
");
	//从文件中读取图书表数据
	readDataFromTxt(L, "data.in.txt");
	displaySqList(L);
	//往线性表中插入元素
	printf("======2、往线性表中插入元素========
");
	ElemType e1;
	strcpy(e1.isbn, "00X");
	strcpy(e1.name, "安徒生童话");
	e1.price = 88.8;

	insertSqList(L, 3, e1);

	//判断线性表是否为空
	if (isEmpty(L)) printf("线性表是空的
");
	else {
		printf("线性表的长度是: %d
", L.length);
	}
	printf("=======3、取第三个元素=======
");

	//取第三个元素
	ElemType e;
	getElem(3, L, e);
	displayElem(e);
	printf("========4、在第三个位置插入元素e========
");

	//在第三个位置插入元素e
	insertSqList(L, 3, e);
	//打印线性表
	displaySqList(L);
	printf("=========5、删除第三个位置的元素========
");

	//删除第三个位置的元素
	deleteSqList(L, 3);
	displaySqList(L);
	printf("=========6、查看元素e在线性表的哪个位置=======
");

	//查看元素e在线性表的哪个位置
	int index=LocateElem(e, L);
	printf("元素e在线性表中的位置: %d
", index);

}

data.in.txt

001 平凡的世界 22.2
002 活着 66.5
003 天之下 33.2
风语者!平时喜欢研究各种技术,目前在从事后端开发工作,热爱生活、热爱工作。