线性表详细讲解
线性表
定义
线性表是由n个数据元素(a1, a2, a3, …, an)组成的有限序列,其中n为表的长度,数据元素的个数也称为表的长度。线性表中的数据元素具有相同的数据类型,相邻元素具有前驱和后继关系。
没有元素则为空表
例子:
稀疏多项式的运算
稀疏多项式是指多项式中只有少量非零项的情况。对于稀疏多项式的运算,一般可以采取以下步骤:
-
表示稀疏多项式:通常使用数组或链表等数据结构来表示稀疏多项式,其中每个非零项包括指数和系数。
-
多项式相加:将两个稀疏多项式相加,首先需要合并同类项(即指数相同的项),然后将系数相加得到结果。
-
多项式相乘:将两个稀疏多项式相乘,需要遍历其中一个多项式的每一项,与另一个多项式相乘并将同类项合并。
-
多项式求导:对于稀疏多项式,可以通过遍历每一项,对每一项的指数进行减一操作,然后将系数乘以原来的指数得到导数。
-
多项式求值:给定一个稀疏多项式和一个值x,可以通过遍历每一项,将x的指数次幂乘以系数,然后将所有结果相加得到多项式在x处的值。
以上是对稀疏多项式的一些基本运算操作,具体实现可以根据具体的数据结构和算法进行设计。
图书信息管理系统
一个图书信息管理系统可以通过线性表来完成,具体可以采用线性表的顺序存储结构或者链式存储结构来实现。
-
使用顺序存储结构实现:可以使用数组来存储图书信息,每本图书对应数组中的一个元素,包括书名、作者、出版社、出版日期等信息。通过数组的下标来访问和操作图书信息。
-
使用链式存储结构实现:可以使用链表来存储图书信息,每个节点包含一本图书的信息,并通过指针来连接各个节点,形成一个链表。这样可以方便地插入、删除和查找图书信息。
无论是顺序存储结构还是链式存储结构,都可以对图书信息进行增加、删除、修改和查询等操作。此外,还可以通过线性表来实现图书的排序、统计、打印等功能。
通过线性表完成图书信息管理系统,可以使得图书信息的管理更加方便和高效。
以下是一个简单的图书信息管理系统的C++代码示例,使用链式存储结构(使用链表)来实现:
#include <iostream>
#include <string>
using namespace std;
struct Book {
string title;
string author;
string publisher;
string publish_date;
Book* next;
};
class BookManagementSystem {
private:
Book* head;
public:
BookManagementSystem() {
head = nullptr;
}
void addBook(string title, string author, string publisher, string publish_date) {
Book* newBook = new Book;
newBook->title = title;
newBook->author = author;
newBook->publisher = publisher;
newBook->publish_date = publish_date;
newBook->next = head;
head = newBook;
}
void removeBook(string title) {
Book* current = head;
Book* previous = nullptr;
while (current != nullptr) {
if (current->title == title) {
if (previous != nullptr) {
previous->next = current->next;
} else {
head = current->next;
}
delete current;
return;
}
previous = current;
current = current->next;
}
}
Book* searchBook(string title) {
Book* current = head;
while (current != nullptr) {
if (current->title == title) {
return current;
}
current = current->next;
}
return nullptr;
}
void displayAllBooks() {
Book* current = head;
while (current != nullptr) {
cout << "Title: " << current->title << ", Author: " << current->author << ", Publisher: " << current->publisher << ", Publish Date: " << current->publish_date << endl;
current = current->next;
}
}
};
// 测试代码
int main() {
BookManagementSystem system;
system.addBook("Python Programming", "John Smith", "ABC Publications", "2021-01-01");
system.addBook("Data Structures and Algorithms", "Alice Johnson", "XYZ Press", "2020-05-15");
system.displayAllBooks();
Book* foundBook = system.searchBook("Python Programming");
if (foundBook != nullptr) {
cout << "Book found - " << foundBook->title << " by " << foundBook->author << endl;
}
system.removeBook("Data Structures and Algorithms");
system.displayAllBooks();
return 0;
}
这个示例代码实现了一个简单的图书信息管理系统,使用了结构体来表示图书(Book结构体),并使用BookManagementSystem类来管理图书信息。在这个示例中,图书信息以链式存储结构的方式存储在链表中,并提供了添加、删除、查找和显示图书信息的功能。
学到这里大家已经成功一半了加油!!!
特点
线性结构
同类型
线性表的类型定义
1.基本操作:
InitList(&L)
操作结果:构造空的线性表L
DestroyList(&L)
初始化条件:线性表L存在
操作结果:销毁线性表L(线性表L不存在)
ClearList(&L)
初始化条件:线性表L存在
操作结果:将线性表L重置为空表(线性表L存在)
ListEmpty(L)
初始化条件:线性表L存在
操作结果:如果线性表为空表,则返回Ture,否则返回False
GetElem(L,i,&e) 返回线性表中第i个元素的值存储在e中
LocateElem(L,e,compare())
compare()判定条件返回第一个元素 没有返回0
PriorElem(L,cur_e,&pre_e)
NextElem(L,cur_e,&next_e)
ListTraverse(&L,visited())
依次对线性表中每个元素调用visited()遍历
线性表的顺序表示和实现
顺序存储的定义
线性表中相邻元素存储地址也相邻(与数组类似)
不同:
线性表长度可变,数组长度不可动态定义
#define LIST INIT SIZE 100
typedef struct{
ElemType elem[LIST_INIT_SIZE];//ElemType可以变成我们需要的类型
int length;//当前长度
}SqList;
例子:
一个函数的表示
#sefine MAXSIZE 1000 //多项式可以达到的最大长度
typedef struct { //多项式非零项的定义
float p; //系数
int e; //指数
}Polynomial;
typedef struct{
Polynomial*elem; //存储空间的基地址
int length; //多项式当前项的个数
}SqList; //多项式顺序存储结构类型为SqList
顺序表的类型定义
数组静态分配
静态分配是指在编译时确定数组的大小,并在程序执行之前分配固定大小的内存空间。在上面的示例中,我们使用了静态分配来创建一个固定大小的Book数组来存储图书信息。具体来说,我们使用了以下代码来定义数组:
const int MAX_SIZE = 100; // 假设最大容量为100
struct Book {
string title;
string author;
string publisher;
string publish_date;
};
class BookManagementSystem {
private:
Book bookList[MAX_SIZE]; // 使用静态分配的数组来存储图书信息
int length;
// ... 其他成员函数
};
在这里,MAX_SIZE
常量定义了数组的最大容量,我们使用这个常量来声明 bookList
数组的大小。这样做的好处是在编译时就确定了数组的大小,使得程序更加高效和可靠。然而,静态分配的数组大小是固定的,不能在运行时动态改变,因此需要在设计时确保数组大小足够满足实际需求。
数组动态分配
在C++中,可以使用动态内存分配来创建数组,这样数组的大小可以在运行时动态确定。动态分配数组使用 new
操作符来分配内存,并使用 delete
操作符来释放内存。下面是一个使用动态分配数组的示例:
#include <iostream>
#include <string>
using namespace std;
struct Book {
string title;
string author;
string publisher;
string publish_date;
};
class BookManagementSystem {
private:
Book* bookList; // 使用指针来动态分配数组
int length;
int capacity;
public:
BookManagementSystem(int initialCapacity) {
capacity = initialCapacity;
bookList = new Book[capacity]; // 使用 new 操作符动态分配数组
length = 0;
}
void addBook(string title, string author, string publisher, string publish_date) {
if (length < capacity) {
bookList[length].title = title;
bookList[length].author = author;
bookList[length].publisher = publisher;
bookList[length].publish_date = publish_date;
length++;
} else {
cout << "Cannot add more books. The list is full." << endl;
}
}
// 其他成员函数
~BookManagementSystem() {
delete[] bookList; // 使用 delete 操作符释放动态分配的数组内存
}
};
// 测试代码
int main() {
BookManagementSystem system(100); // 初始化时指定初始容量为100
system.addBook("Python Programming", "John Smith", "ABC Publications", "2021-01-01");
system.addBook("Data Structures and Algorithms", "Alice Johnson", "XYZ Press", "2020-05-15");
// ... 其他测试代码
return 0;
}
在上面的示例中,bookList
被声明为 Book*
类型的指针,然后在构造函数中使用 new
操作符动态分配了一个包含 capacity
个元素的 Book
类型数组。在析构函数中使用 delete
操作符释放了动态分配的数组内存。这种方法使得数组的大小可以在运行时动态确定,从而更加灵活地满足实际需求。
SqList L;
L.date = (ElemType*)malloc(size(ElemType)*MaxxSize);
c中free§释放指针p所指变量的存储空间,即彻底删除一个变量
类型决定分配的空间
参数传递
实参与形参
参数传递的方式
- 传值方式
- 传地址
线性表与顺序表的存储表达
逻辑位序和物理位序相差1
算法预定义常量:
//函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFASLBLE -1
#define OVERFLOW -2
//Status 是函数的类型,其值是函数结果状态代码
typedef int Status;
typedef char ElemType;
算法
线性表L初始化(参数引用)
Status InitList_Sq(SqList&L){ //构造一个空的顺序表
L.elem = new ElemType[MAXSIZE]; //为顺序表分配空间
if(!L.elem)exit(OVERFLOW); //存储分配失败异常处理对错误要提前处理防止后面出错导致程序崩溃
L.length = 0; //空表长度为0
return OK;
}
求线性表L的长度
判断线性表L是否为空
顺序表取值(随机存取)(按值查找)
顺序表的插入(小心溢出length判断,插入范围)
Status ListInsert_Sq(SqList &L,int i,ElemType e){
if(i<1||i>L.length+1) return ERROR; //i值不合法
if(L.length==MAXSIZE) return ERROR; //当前存储空间已满
for(j=L.length-1;j>=i;j--)
L.elem[j+1]=L.elem[j]; //插入位置及之后的元素后移
L.elem[i-1]=e; //将新元素e放入第i个位置
L.length++; //表长加1
return OK;
}
线性表删除算法(在执行前要进行异常判断)
小结
核心:线性表访问每个元素的时间是相等的
线性表是一种常见的数据结构,它是由n个具有相同特性的数据元素组成的有限序列。线性表中的数据元素之间存在着一对一的关系,即除了第一个元素之外,每个元素都有且仅有一个直接前驱元素;除了最后一个元素之外,每个元素都有且仅有一个直接后继元素。
以下是关于线性表的一些要点:
-
特点:
- 顺序存储:线性表的元素在物理上是顺序存储的,可以使用数组来实现。
- 链式存储:线性表的元素在物理上不一定是顺序存储的,可以使用链表来实现。
-
基本操作:
- 插入:在指定位置插入一个元素。
- 删除:删除指定位置的元素。
- 查找:根据位置或者元素的值查找元素。
- 遍历:依次访问线性表中的每个元素。
-
实际应用:
- 线性表在各种算法和数据结构中都有广泛的应用,例如栈、队列、链表等都是基于线性表的基本操作进行实现的。
- 在实际问题中,线性表也经常被用来表示和处理一系列具有顺序关系的数据,比如学生成绩、员工工资等。
-
常见实现:
- 顺序表:使用数组实现的线性表,支持随机访问,但插入和删除操作可能需要移动大量元素。
- 链表:使用指针实现的线性表,支持快速的插入和删除操作,但不支持随机访问。
总之,线性表是一种非常基础的数据结构,它提供了对一系列数据进行管理和操作的基本方法,是学习数据结构和算法的重要基础。
本文作者:2c237c6
本文链接:https://www.cnblogs.com/27dCnc/p/18568685
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步