数据结构-顺序表-代码
顺序表 - 用顺序存储的方式实现线性表
定义
-
通过数据元素的大小 + 线性表首元素的地址 == 定位顺序表的元素位置
数据元素的大小:
sizeof(Elem Type)
会返回一个 值=Elem 的大小 -
特点
随机访问:在
O(1)
时间找到指定位置的元素存储密度高:每个节点只存储数据元素,(不存在指针等占用空间)
拓展容量不方便
数据的增删操作不方便
顺序表的静态分配
#include <stdio.h>
#include <iostream>
using namespace std;
#define MAXSIZE 20 //宏定义最大长度
typedef int ElemType; //定义数据类型
struct SqTable
{
ElemType data[MAXSIZE]; // 存储静态表中的数据
int length; // 静态表中元素的个数
};
// 初始化,对于静态表,在结构体定义的时候就已经声明了数据空间
void SqTableInit(SqTable* sq_table)
{
for (int temp = 0; temp < MAXSIZE; temp++)
{
sq_table->data[temp] = 0; // 数据初始化
}
sq_table->length = 0; // 长度置0
}
// 数据初始化
bool SqTableInitData(SqTable* sq_table)
{
cout << "Please cin the number of sequence element" << endl;
cin >> sq_table->length; // 输入静态表元素的个数
if (sq_table->length > MAXSIZE)
{
cout << "too many element" << endl; // 元素个数超范围
sq_table->length = 0;
return false;
}
cout << "Please cin the element of sequence" << endl;
for (int temp = 0; temp < sq_table->length; temp++) // 输入顺序表元素
{
cin >> sq_table->data[temp];
}
return true;
}
// 向表尾插入数据
bool SqTableInsertAtTail(SqTable* sq_table, ElemType e)
{
if (sq_table->length == MAXSIZE) // 顺序表已满
{
cout << "the sequence is full" << endl;
return false;
}
sq_table->data[sq_table->length] = e; // 赋值
sq_table->length++; // 长度++
return true;
}
// 向位置pos插入数据,pos是位序,对应下标为pos-1
bool SqTableInsertAtPos(SqTable* sq_table, int pos, ElemType e)
{
if (pos < 1 || pos > MAXSIZE) // 输入的位置超范围
{
cout << "the position is illegal" << endl;
return false;
}
pos--; // 获得下标
for (int temp = sq_table->length - 1; temp >= pos; temp--) // **从后往前移动数据**
{
sq_table->data[temp + 1] = sq_table->data[temp];
}
sq_table->data[pos] = e; // 赋值
sq_table->length++;
return true;
}
// 删除位置pos的数据
bool SqTableDeleteAtPos(SqTable* sq_table, int pos, ElemType* e)
{
if (pos < 1 || pos > MAXSIZE) // 输入的位置超范围
{
cout << "the position is illegal" << endl;
return false;
}
pos--; // 获得下标
*e = sq_table->data[pos]; // 取值
for (int temp = pos; temp < sq_table->length; temp++) // **从前往后移动数据**
{
sq_table->data[temp] = sq_table->data[temp + 1];
}
sq_table->length--;
return true;
}
// 查找值为e的元素的位序
int SqTableFindE(SqTable sq_table, ElemType e)
{
for (int temp = 0; temp < sq_table.length; temp++) // 遍历数组
{
if (sq_table.data[temp] == e)
{
return (temp + 1); // 获得位序
}
}
cout << "the element is not find" << endl;
return -1;
}
// 查找位序为pos的元素
bool SqTableGetValue(SqTable sq_table, ElemType* e, int pos)
{
if (pos < 0 || pos >= sq_table.length) // 位序超范围
{
cout << "the position is illegal" << endl;
return false;
}
*e = sq_table.data[pos - 1]; // pos-1为下标
return true;
}
// 顺序表输出
void SqTablePrint(SqTable sq_table)
{
for (int temp = 0; temp < sq_table.length; temp++) // 遍历数组输出
{
cout << sq_table.data[temp] << " ";
}
cout << endl;
}
int main()
{
ElemType e = 0;
int pos = 0;
SqTable sq_table;
SqTableInit(&sq_table);
SqTableInitData(&sq_table);
SqTablePrint(sq_table);
cout << "Please cin the element that will be inserted" << endl;
cin >> e;
SqTableInsertAtTail(&sq_table, e);
SqTablePrint(sq_table);
cout << "Please cin the location of the element that will be inserted" << endl;
cin >> pos >> e;
SqTableInsertAtPos(&sq_table, pos, e);
SqTablePrint(sq_table);
cout << "Please cin the location of the element that will be deleted" << endl;
cin >> pos;
SqTableDeleteAtPos(&sq_table, pos, &e);
cout << "the deleted element: " << e << endl;
SqTablePrint(sq_table);
cout << "Please cin the element that will be find" << endl;
cin >> e;
cout << "the element is at: " << SqTableFindE(sq_table, e) << endl;
cout << "Please cin a location" << endl;
cin >> pos;
SqTableGetValue(sq_table, &e, pos);
cout << "the element at location is: " << e << endl;
return 0;
}
顺序表的动态分配
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
using namespace std;
#define SIZE_INIT 2 // 初始化顺序表大小
#define CREASE_LEN 2 // 扩容时的增量
typedef int ElemType;
struct SqTable
{
ElemType* data; // 可变动态数组
int length; // 元素个数
int size; // 顺序表容量
};
// 顺序表初始化
bool SqTableInit(SqTable* sq_table)
{
// 请求空间,malloc返回的是一个void*类型,因此要进行强制转换
sq_table->data = (ElemType*)malloc(SIZE_INIT * (sizeof(ElemType)));
if (sq_table->data == NULL) // 请求空间失败
{
return false;
}
sq_table->length = 0; // 初始化元素个数
sq_table->size = SIZE_INIT; // 初始化容量
return true;
}
// 使用relloc进行扩容,使用relloc扩容,容量是在原空间上增加,不用转移数据
bool SqTableIncreaseByRelloc(SqTable* sq_table)
{
sq_table->data = (ElemType*)realloc(sq_table->data, (sq_table->size + CREASE_LEN) * (sizeof(ElemType)));
if (sq_table->data == NULL) // 请求空间失败
{
return false;
}
sq_table->size = sq_table->size + CREASE_LEN;
return true;
}
// 使用malloc进行扩容,malloc会重新分配一片空间,因此需要转移数据
bool SqTableIncreaseByMalloc(SqTable* sq_table)
{
ElemType* storage = sq_table->data; // 使用指针变量暂存原数组的首地址
sq_table->data = (ElemType*)malloc((sq_table->size + CREASE_LEN) * (sizeof(ElemType)));
if (sq_table->data == NULL) // 请求空间失败
{
return false;
}
for (int temp = 0; temp < sq_table->length; temp++) // 转移数据
{
sq_table->data[temp] = storage[temp];
}
sq_table->size = sq_table->size + CREASE_LEN;
return true;
}
// 向顺序表尾插入数据
bool SqTableInsertAtTail(SqTable* sq_table, ElemType e)
{
if (sq_table->length == sq_table->size) // 需要扩容
{
bool SqIncreaseResult = SqTableIncreaseByRelloc(sq_table); // relloc尝试扩容
if (!SqIncreaseResult) // 扩容失败
{
cout << "the sequence is full, and capacity increase failt" << endl;
return false;
}
}
sq_table->data[sq_table->length] = e; // 赋值
sq_table->length++;
return true;
}
// 向位置pos插入数据,pos是位序,对应下标为pos-1
bool SqTableInsertAtPos(SqTable* sq_table, int pos, ElemType e)
{
if (sq_table->length == sq_table->size) // 扩容
{
bool SqIncreaseResult = SqTableIncreaseByMalloc(sq_table); // malloc尝试扩容
if (!SqIncreaseResult) // 扩容失败
{
cout << "the sequence is full, and capacity increase failt" << endl;
return false;
}
}
pos--; // 获得下标
for (int temp = sq_table->length - 1; temp >= pos; temp--) // **从后往前移动数据**
{
sq_table->data[temp + 1] = sq_table->data[temp];
}
sq_table->data[pos] = e; // 赋值
sq_table->length++;
return true;
}
// 删除位序pos的元素
bool SqTableDeleteAtPos(SqTable* sq_table, int pos, ElemType* e)
{
if (pos < 1 || pos > sq_table->length) // 输入的位序超范围
{
cout << "the position is illegal" << endl;
return false;
}
pos--; // 获得下标
*e = sq_table->data[pos];
for (int temp = pos; temp < sq_table->length; temp++) // **从左往右移动数据**
{
sq_table->data[temp] = sq_table->data[temp + 1];
}
sq_table->length--; // 元素个数更新
return true;
}
// 查找位序pos的元素
bool SqTableGetValue(SqTable sq_table, ElemType* e, int pos)
{
if (pos < 1 || pos > sq_table.length) // 输入的位序超范围
{
cout << "the position is illegal" << endl;
return false;
}
pos--; // 获得下标
*e = sq_table.data[pos];
return true;
}
// 查找元素e
int SqTableFindE(SqTable sq_table, ElemType e)
{
for (int temp = 0; temp < sq_table.length; temp++) // 遍历指针数组
{
if (sq_table.data[temp] == e)
{
return (temp + 1); // temp+1获得位序
}
}
cout << "the element is not find" << endl;
return -1;
}
// 数据初始化
bool SqTableInitData(SqTable* sq_table)
{
cout << "Please cin the number of sequence element" << endl;
int sequence_length = 0;
cin >> sequence_length; // 输入初始化时顺序表中元素的个数
cout << "Please cin the element of sequence" << endl;
for (int temp = 0; temp < sequence_length; temp++) // 输入顺序表元素
{
ElemType temp_in;
cin >> temp_in;
SqTableInsertAtTail(sq_table, temp_in); // 直接向表尾插入元素,时间复杂度O(1)
}
return true;
}
// 顺序表输出
void SqTablePrint(SqTable sq_table)
{
for (int temp = 0; temp < sq_table.length; temp++) // 遍历输出
{
cout << sq_table.data[temp] << " ";
}
cout << endl;
}
int main()
{
ElemType e = 0;
int pos = 0;
SqTable sq_table;
SqTableInit(&sq_table);
SqTableInitData(&sq_table);
SqTablePrint(sq_table);
cout << "Please cin the location of the element that will be inserted" << endl;
cin >> pos >> e;
SqTableInsertAtPos(&sq_table, pos, e);
SqTablePrint(sq_table);
cout << "Please cin the location of the element that will be deleted" << endl;
cin >> pos;
SqTableDeleteAtPos(&sq_table, pos, &e);
cout << "the deleted element: " << e << endl;
SqTablePrint(sq_table);
cout << "Please cin the element that will be find" << endl;
cin >> e;
cout << "the element is at: " << SqTableFindE(sq_table, e) << endl;
cout << "Please cin a location" << endl;
cin >> pos;
SqTableGetValue(sq_table, &e, pos);
cout << "the element at location is: " << e << endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报