一顺序表的创建
1.静态顺序表
#define max 10
typedef int SLDataType;//更改类型 名字
typedef struct SeqList
{
SLDataType data[max];
int size;//数据个数
int capacity;// 容量大小
}SL;
静态顺序表大小固定一,一般不进行采用
1.动态顺序表
typedef int SLDataType;//更改类型 名字
typedef struct SeqList//结构体的类型名,使用typedef进行简化
{
SLDataType* data;
int size;//数据个数
int capacity;// 容量大小
}SL;//结构体的别名
用指针来控制顺序表的大小,就进行动态开辟空间
二顺序表的初始化
void SeqListInit(SL* ps)
{
assert(ps != NULL); //断言
ps->data = (SLDataType*) malloc(sizeof(SLDataType) * INIT_N);
if (ps->data == NULL)
{
perror("malloc");
}
ps->capacity = INIT_N;
ps->size = 0;
}
使用malloc进行开辟空间,进行初始化,开辟的空间大小为sizeof(SLDataType)*INIT_N,
sizeof(SLDataType)计算SLDataType的字节
INIT_N在头文件中进行声明 “#define INIT_N 4”意思是进行宏定义,定义为整数4
(SLDataType*)进行强制转换成这个SLDataType*的类型
顺序表的清除
void SeqListDestroy(SL* ps)
{
// 使用断言来确保传入的指针不为空。如果ps为空,程序会在这里终止并输出错误信息。
assert(ps != NULL); //断言
// 释放顺序列表存储数据的动态数组所占用的内存。
free(ps->data);
// 将数据指针设为NULL,以避免悬挂指针(dangling pointer)问题。
ps->data = NULL;
// 重置顺序列表的容量和大小属性为0。
ps->capacity = ps->size = 0;
}
对顺序表进行清楚,全部设置为0;
顺序表的尾增
void SeqListPushBack(SL* ps, SLDataType x)
{
// 使用断言来确保传入的指针不为空
assert(ps != NULL); //断言
// 检查当前列表是否已满(即元素数量是否等于容量)
if (ps->size == ps->capacity)
{
// 如果已满,则尝试重新分配内存,将容量扩大一倍
SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);
// 检查realloc是否成功
if (tmp == NULL)
{
// 如果realloc失败,输出错误信息并返回
perror("realloc");
return;
}
// 如果realloc成功,更新数据指针和容量
ps->data = tmp;
ps->capacity = ps->capacity * 2;
}
// 将新元素添加到列表的末尾
ps->data[ps->size] = x;
// 增加列表的大小
ps->size++;
// 另一种写法
// ps->data[ps->size++] = x;
}
在顺序表尾部进行添加元素
顺序表的头删
void SeqListPopBack(SL* ps)
{
assert(ps != NULL); //断言
if (ps->size > 0) // 确保size不为0
{
//ps->data[ps->size - 1] = 0;
ps->size--; // 先减少size
}
}
对顺序表的头部进行删除
顺序表的打印
void SLPrint(SL* ps)
{
assert(ps != NULL); //断言(ps != NULL); //断言
for (size_t i = 0; i < ps->size; i++)//进入循环
{
printf("%d ", ps->data[i]);//打印每一个元素
}
printf("\n");//进行换行
}
对顺序表进行打印
顺序表的头插
void SeqListPushFront(SL* ps, SLDataType x)
{
assert(ps != NULL); // 断言
// 扩大容量(如果需要)
if (ps->size == ps->capacity)
{
SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * (ps->capacity * 2));
if (tmp == NULL)
{
perror("realloc");
return;
}
ps->data = tmp;
ps->capacity *= 2;
}
// 将所有元素向后移动一个位置
for (size_t i = ps->size; i > 0; i--)
{
ps->data[i] = ps->data[i - 1];
}
// 在列表开头插入新元素
ps->data[0] = x;
ps->size++;
}
在顺序表头部进行插入
顺序表的选择插入
void SeqListInsert(SL* ps, int p, SLDataType x)
{
assert(ps != NULL);
assert(p >= 0 && p <= ps->size); // 确保p是有效的插入位置
if (ps->size == ps->capacity)
{
SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("realloc");
return;
}
ps->capacity *= 2;
ps->data = tmp; // 更新ps->data指针
}
// 从p位置开始向前移动元素以腾出空间
for (size_t i = ps->size; i > (size_t)p; i--)
{
ps->data[i] = ps->data[i - 1];
}
// 在p位置插入x
ps->data[p] = x;
ps->size++;
}
插入的升级版本,可以选择位置进行插入
顺序表的选择删除
void SeqListErase(SL* ps, int p)
{
assert(ps != NULL);
assert(p >= 0 && p < ps->size); // 确保p是有效的删除位置
// 如果列表不为空且p是有效的索引
if (ps->size > 0 && p >= 0 && p < ps->size)
{
// 从p+1开始向前移动元素
for (size_t i = p; i < ps->size - 1; i++)
{
ps->data[i] = ps->data[i + 1]; // 注意这里,我们用的是i而不是i-1
}
// 更新列表大小
ps->size--;
}
// 如果ps->size已经是0或者p无效,assert会触发,程序会在调试模式下停止
}
删除的升级版本,选择位置进行删除
顺序表的查找
void SeqListFind(SL* ps, SLDataType x)
{
assert(ps != NULL);
int found = 0; // 使用一个标志变量来表示是否找到值
for (size_t i = 0; i < ps->size; i++)
{
if (ps->data[i] == x)
{
printf("%zu: %d\n", i, ps->data[i]); // 打印索引和值,以便知道在哪个位置找到的
found = 1; // 标记为已找到
break; // 跳出循环,因为已经找到了值
}
}
if (!found)
{
printf("没有找到\n");
}
}
对顺序表进行查找,查找里面的元素
顺序表的修改
void SeqList_Update(SL* ps, int p, SLDataType x)
{
assert(ps != NULL);
// 确保索引p在有效范围内
if (p < 0 || p >= ps->size)
{
printf("索引无效,无法修改\n");
return;
}
// 使用索引p来更新元素
ps->data[p] = x;
// 更新操作成功,没有返回语句(void函数)
}
用来修改顺序表
成果截图
头文件
SL.h
#pragma once
#include<stdlib.h>
#include<stdio.h>
#include<assert.h>
#define INIT_N 4
//顺序表的类型定义、接口函数声明、引用的头文件
typedef int SLDataType;
//类型名称SLDataType
typedef struct SeqList
{
SLDataType* data;
int size;//数据个数
int capacity;// 容量大小
}SL;
void SeqListInit(SL *ps);
void SeqListDestroy(SL* ps);
void SeqListPushBack(SL* ps);
void SeqListPopBack(SL* ps);
void SLPrint(SL* ps);
void SeqListPushFront(SL* ps, SLDataType x);
void SeqListInsert(SL* ps ,int p, SLDataType x);
void SeqListErase(SL* ps, int p);
void SeqListFind(SL* ps, SLDataType x);
void SeqList_Update(SL*ps ,int p, SLDataType x);
主函数
test.c
#include"SL.h"
SL seqList;
void TestSeqList()
{
SeqListInit(&seqList);
SeqListPushBack(&seqList, 1);
SeqListPushBack(&seqList, 2);
SeqListPushBack(&seqList, 3);
printf("尾插入\n");
SLPrint(&seqList);
SeqListPushBack(&seqList, 4);
SeqListPushBack(&seqList, 5);
SeqListPushBack(&seqList, 6);
SeqListPushBack(&seqList, 7);
printf("尾插入\n");
SLPrint(&seqList);
SeqListPushBack(&seqList, 5);
SeqListPushBack(&seqList, 6);
SeqListPushBack(&seqList, 7);
printf("尾插入\n");
SLPrint(&seqList);
printf("尾删\n");
SeqListPopBack(&seqList);
SeqListPopBack(&seqList);
SLPrint(&seqList);
printf("头插入\n");
SeqListPushFront(&seqList, 9);
SLPrint(&seqList);
printf("选择插入\n");
SeqListInsert(&seqList,5,1);
SLPrint(&seqList);
printf("选择删除\n");
SeqListErase(&seqList, 5);
SLPrint(&seqList);
printf("查找");
SeqListFind(& seqList, 5);
SLPrint(&seqList);
printf("查找");
SeqListFind(&seqList, 20);
SLPrint(&seqList);
printf("改\n");
SeqList_Update(&seqList, 5, 10);
SLPrint(&seqList);
}
int main()
{
TestSeqList();
SeqListDestroy(&seqList);
return 0;
}
SL.c
//顺序表接口函数的实现
#include"SL.h"
void SeqListInit(SL* ps)
{
assert(ps != NULL); //断言
ps->data = (SLDataType*) malloc(sizeof(SLDataType) * INIT_N);
if (ps->data == NULL)
{
perror("malloc");
}
ps->capacity = INIT_N;
ps->size = 0;
}
void SeqListDestroy(SL* ps)
{
assert(ps != NULL); //断言
free(ps->data);
ps->data = NULL;
ps->capacity = ps->size = 0;
}
void SeqListPushBack(SL* ps, SLDataType x)
{
assert(ps != NULL); //断言
if (ps->size==ps->capacity)
{
SLDataType* tmp = (SLDataType*)realloc(ps->data,sizeof(SLDataType) *ps->capacity *2);
if (tmp==NULL)
{
perror("realloc");
return;
}
ps->capacity = ps->capacity * 2;
}
ps->data[ps->size] = x;
ps->size++;
//或者
//ps->data[ps->size++] = x;
}
void SeqListPopBack(SL* ps)
{
assert(ps != NULL); //断言
if (ps->size > 0) // 确保size不为0
{
//ps->data[ps->size - 1] = 0;
ps->size--; // 先减少size
}
}
void SLPrint(SL* ps)
{
assert(ps != NULL); //断言(ps != NULL); //断言
for (size_t i = 0; i < ps->size; i++)
{
printf("%d ", ps->data[i]);
}
printf("\n");
}
void SeqListPushFront(SL* ps, SLDataType x)
{
assert(ps != NULL); //断言(ps != NULL); //断言
if (ps->size == ps->capacity)
{
SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("realloc");
return;
}
ps->capacity = ps->capacity * 2;
ps->data = tmp; // 更新ps->data指针
}
for (size_t i =0; i < ps->size; i++)
{
ps->data[ps->size+1] = ps->data[ps->size];
}
ps->data[0] = x;
ps->size++;
}
void SeqListInsert(SL* ps, int p, SLDataType x)
{
assert(ps != NULL);
assert(p >= 0 && p <= ps->size); // 确保p是有效的插入位置
if (ps->size == ps->capacity)
{
SLDataType* tmp = (SLDataType*)realloc(ps->data, sizeof(SLDataType) * ps->capacity * 2);
if (tmp == NULL)
{
perror("realloc");
return;
}
ps->capacity *= 2;
ps->data = tmp; // 更新ps->data指针
}
// 从p位置开始向前移动元素以腾出空间
for (size_t i = ps->size; i > (size_t)p; i--)
{
ps->data[i] = ps->data[i - 1];
}
// 在p位置插入x
ps->data[p] = x;
ps->size++;
}
void SeqListErase(SL* ps, int p)
{
assert(ps != NULL);
assert(p >= 0 && p < ps->size); // 确保p是有效的删除位置
for (size_t i = p; i < ps->size; i++)
{
ps->data[i-1] = ps->data[i];
}
ps->size--;
}
void SeqListFind(SL* ps, SLDataType x)
{
assert(ps != NULL);
int found = 0; // 使用一个标志变量来表示是否找到值
for (size_t i = 0; i < ps->size; i++)
{
if (ps->data[i] == x)
{
printf("%zu: %d\n", i, ps->data[i]); // 打印索引和值,以便知道在哪个位置找到的
found = 1; // 标记为已找到
break; // 跳出循环,因为已经找到了值
}
}
if (!found)
{
printf("没有找到\n");
}
}
void SeqList_Update(SL* ps, int p, SLDataType x)
{
assert(ps != NULL);
// 确保索引p在有效范围内
if (p < 0 || p >= ps->size)
{
printf("索引无效,无法修改\n");
return;
}
// 使用索引p来更新元素
ps->data[p] = x;
// 更新操作成功,没有返回语句(void函数)
}