顺序表的增删查改

首先顺序表的创建需要用到结构体,顺序表中包含三个变量,分别是数组(存储数据),有效数据个数,数组的大小。这里创建的是动态顺序表。

typedef int SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{
    SLDataType* a;
    int size;     // 有效数据个数
    int capacity; // 空间容量
}SL;

使用typedef将int转换成SLDataType,这样做有利于修改数组的类型。

这里创建了头文件SL.h,函数的声明都放在了头文件中


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#define INIT_CAPACITY 4
typedef int SLDataType;
// 动态顺序表 -- 按需申请
typedef struct SeqList
{
    SLDataType* a;
    int size;     // 有效数据个数
    int capacity; // 空间容量
}SL;

//初始化和销毁
void SLInit(SL* ps);//初始化
void SLDestroy(SL* ps);//销毁
void SLPrint(SL* ps);//打印
//扩容
void SLCheckCapacity(SL* ps);

//头部插入删除 / 尾部插入删除
void SLPushBack(SL* ps, SLDataType x);//头插
void SLPopBack(SL* ps);//头删
void SLPushFront(SL* ps, SLDataType x);//尾插
void SLPopFront(SL* ps);//尾删

//指定位置之前插入/删除数据
void SLInsert(SL* ps, int pos, SLDataType x);//指定位置插入
void SLErase(SL* ps, int pos);//指定位置删除
int SLFind(SL* ps, SLDataType x);//查找

首先实现顺序表的初始化

void SLInit(SL* ps)

{
    ps->a = NULL;
    ps->capacity = 0;
    ps->size = 0;
}

扩容的实现

void SLCheckCapacity(SL* ps1)
{
    SLDataType newcapacity = ps1->capacity == 0 ? 4 : 2 * ps1->capacity;
    SLDataType* tmp = (SLDataType*)realloc(ps1->a, newcapacity * sizeof(int));
    if (tmp == NULL)
    {
        perror("realloc tmp");
        exit(1);
    }
    ps1->a = tmp;
}

第一次进入时数组a为空,故要先开辟空间,又或者当空间满了,即ps->size 和 ps->capacity相等时开辟空间,一般是开辟2倍的空间。

头插的实现

void SLPushBack(SL* ps, SLDataType x)
{
    if (ps->size == ps->capacity)
    {
        SLCheckCapacity(ps);//这里是给ps指向的数组a进行扩容,故不需要传址
    }
    int i = 0;
    for (i = ps->size; i > 0; i--)
    {
        ps->a[i] = ps->a[i - 1];
    }
    ps->a[0] = x;
    ps->size++;
}

将数组元素全部往后移动一个位置,空出第一个位置。

头删的实现

void SLPopBack(SL* ps)
{
    assert(ps);
    assert(ps->size);//当size为0时,也不能执行删除
    int i = 0;
    for (i = 0; i < ps->size; i++)
    {
        ps->a[i] = ps->a[i + 1];
    }
    ps->size--;
}

依次将后一个位置的内容拷贝到前一个位置上。

尾插的实现

void SLPushFront(SL* ps, SLDataType x)
{
    if (ps->size == ps->capacity)
    {
        SLCheckCapacity(ps);
    }
    ps->a[ps->size] = x;
    ps->size++;
}

指向size位置内容等于x

尾删的实现

void SLPopFront(SL* ps)
{
    assert(ps);
    assert(ps->size);
    ps->size--;
}

size--即可,原size的内容对顺序表没有影响

任意位置插入

void SLInsert(SL* ps, int pos, SLDataType x)
{
    if (ps->size == ps->capacity)
    {
        SLCheckCapacity(ps);
    }
    int i = 0;
    for (i = ps->size; i > pos; i--)
    {
        ps->a[i] = ps->a[i - 1];
    }
    ps->a[pos] = x;
    ps->size++;
}

在pos位置到size位置的内容向后移动一个位置,空出pos位置,插入x

任意位置删除

void SLErase(SL* ps, int pos)
{
    assert(ps);
    assert(ps->size && pos <= ps->size);//并且pos要<=size
    int i = 0;
    for (i = pos; i < ps->size; i++)
    {
        ps->a[i] = ps->a[i + 1];
    }
    ps->size--;
}

参考头删,将pos+1位置到size位置的内容向前移动一个位置

查找

int SLFind(SL* ps, SLDataType x)
{
    int i = 0;
    for (i = 0; i < ps->size; i++)
    {
        if (ps->a[i] == x)
        {
            printf("找到了%d\n", x);
            return 1;
        }
    }
    printf("没找到%d\n", x);
    return 0;
}

挨个查询

创建SL.c文件,完成函数的实现

#include "SL.h"

//初始化
void SLInit(SL* ps)
{
	ps->a = NULL;
	ps->capacity = 0;
	ps->size = 0;
}

//销毁
void SLDestroy(SL* ps)
{
	free(ps->a);
}

//打印
void SLPrint(SL* ps)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		printf("%d ", ps->a[i]);
	}
}

//扩容
void SLCheckCapacity(SL* ps1)
{
	SLDataType newcapacity = ps1->capacity == 0 ? 4 : 2 * ps1->capacity;
	SLDataType* tmp = (SLDataType*)realloc(ps1->a, newcapacity * sizeof(int));
	if (tmp == NULL)
	{
		perror("realloc tmp");
		exit(1);
	}
	ps1->a = tmp;
}

//头插
void SLPushBack(SL* ps, SLDataType x)
{
	if (ps->size == ps->capacity)
	{
		SLCheckCapacity(ps);//这里是给ps指向的数组a进行扩容,故不需要传址
	}
	int i = 0;
	for (i = ps->size; i > 0; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[0] = x;
	ps->size++;
}

//头删
void SLPopBack(SL* ps)
{
	assert(ps);
	assert(ps->size);//当size为0时,也不能执行删除
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

//尾插
void SLPushFront(SL* ps, SLDataType x)
{
	if (ps->size == ps->capacity)
	{
		SLCheckCapacity(ps);
	}
	ps->a[ps->size] = x;
	ps->size++;
}

//尾删
void SLPopFront(SL* ps)
{
	assert(ps);
	assert(ps->size);
	ps->size--;
}

//任意位置插入
void SLInsert(SL* ps, int pos, SLDataType x)
{
	if (ps->size == ps->capacity)
	{
		SLCheckCapacity(ps);
	}
	int i = 0;
	for (i = ps->size; i > pos; i--)
	{
		ps->a[i] = ps->a[i - 1];
	}
	ps->a[pos] = x;
	ps->size++;
}

//任意位置删除
void SLErase(SL* ps, int pos)
{
	assert(ps);
	assert(ps->size && pos <= ps->size);//并且pos要<=size
	int i = 0;
	for (i = pos; i < ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

//查找

int SLFind(SL* ps, SLDataType x)
{
	int i = 0;
	for (i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			printf("找到了%d\n", x);
			return 1;
		}
	}
	printf("没找到%d\n", x);
	return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值