数据结构(顺序表的增删查改)

一顺序表的创建

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函数)  
}

  • 11
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值