【顺序表】


顺序表
本质上就是结构体数组,数据在内存中 连续存放的:

顺序表结构

//动态顺序表
typedef int SLDataType;
typedef struct SqeList
{
	SLDataType* a;
	int size;//数据个数
	int capacity;//容量
}SL;

顺序表接口

void SLInit(SL* ps);//初始化顺序表
void SLPrint(SL* ps);//打印顺序表
void SLPushFront(SL* ps,SLDataType x);//头插
void SLPushBack(SL* ps,SLDataType x);//尾插
void SLPopFront(SL* ps);//头删
void SLPopBack(SL* ps);//尾删
void SLDestory(SL* ps);//销毁
void SLInsert(SL* ps,int pos,SLDataType x);//选择插入
void SLErase(SL* ps,int pos);//选择删除
void SLFind(Sl* ps,int pos);//查找
void SLModify(SL* ps,int pos,SLDataType x);//修改数据

初始化顺序表

void SLInit(SL* ps)
{
	assert(ps);
	ps->a = NULL;
	ps->size = ps->capacity = 0;
}

打印顺序表

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

头插

头插,当容量满的时候,我们要增容,才能插入。
并且头插之前,还需要挪动当前所有数据,这便会导致顺序表头插不方便。

void SLCheckCapacity(SL* ps)
{
	if(ps->size==ps->capacity)
	{
		int newcapacity = capacity == 0 ? 4:capacity*2;
		SLDdataType* tmp = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));
		assert(tmp);//断言是否realloc成功
	}
	ps->a = tmp;
	ps->capacity = newCapacity;
}

void SLPushFront(SL* ps,SLDataType x)
{
	assert(ps);
	//扩容
	SLCheckCapacity(ps);
	//挪动数据
	int end = ps->size - 1;
	while (end >= 0)
	 {
		ps->a[end + 1] = ps->a[end];
		--end;
	 }
	ps->a[0] = x;
	ps->size++;
}
	

尾插

void SListPushBack(SL* ps, SLDdataType x)
 {
	assert(ps);
	//扩容
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

头删

头删时,要注意顺序表中要有数据,其次头删需要将除第一个数据后的所有数据向前挪动(从左开始挪动)。

void SLPopFront(SL* ps)
 {
	assert(ps);
	assert(ps->size > 0);
	int begin = 1;
	//挪动数据
	while (begin < ps->size)
	 {
		ps->a[begin - 1] = ps->a[begin];
		++begin;
	 }
	ps->size--}

尾删

尾删只需将ps->size–即可

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

销毁

void SLDestory(SL* ps)
{
	assert(ps);
	free(ps->a);
	ps->a=NULL;
	ps->size=ps->capacity=0;
}

选择插入

此处也需要扩容和挪动数据,还需注意控制pos的位置不能越界。

void SLInsert(SL* ps, int pos, SLDataType x) {
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= pos)
	 {
		ps->a[end + 1] = ps->a[end];
		end--;
	 }
	ps->a[pos] = x;
	ps->size++;
}
//有了这个之后,我们要尾插头插都可以复用了
}

选择删除

void SLErase(SL* ps, int pos)
 {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	int begin = pos;
	while (begin < ps->size - 1)
	 {
		ps->a[begin] = ps->a[begin + 1];
		++begin;
	 }
	ps->size--;
}

查找

int SLFind(SL* ps, SLDataType x)
 {
	assert(ps);
	for (int i = 0; i < ps->size; i++)
	 {
		if (ps->a[i] == x) {
			return i;//找到了
		}
	}
	return -1;//找不到
}

修改数据

void SLModify(SL* ps, int pos, SLDdataType x)
 {
	assert(ps);
	assert(pos >= 0 && pos < ps->size);
	ps->a[pos] = x;
}

test.c

#include "SeqList.h"

void TestSeqList1()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	SLPrint(&s1);

	SLPopBack(&s1);
	SLPrint(&s1);
	SLDestory(&s1);
}

void TestSeqList4()
{
	SL s1;
	SLInit(&s1);
	SLPushBack(&s1, 1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPushBack(&s1, 5);
	//SLPopFront(&s1);
	//SLInsert(&s1, 2, 20);
	SLErase(&s1,2);
	SLErase(&s1, 0);
	SLPrint(&s1);
}
int main()
{
	TestSeqList4();
	return 0;
}

SeqList.h

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>


typedef int SLDateType;
typedef struct SeqList
{
	SLDateType* a;
	int size;
	int capacity;
}SL;

//初始化顺序表
void SLInit(SL* ps);

//尾插
void SLPushBack(SL* ps, SLDateType x);

//头插
void SLPushFront(SL* ps, SLDateType x);

//打印
void SLPrint(SL* ps);

//尾删
void SLPopBack(SL* ps);

//销毁
void SLDestory(SL* ps);

//头删 
void SLPopFront(SL* ps);

//查找
void SLFind(SL* ps, SLDateType x);

//选择插入
void SLInsert(SL* ps,int pos, SLDateType x);

//选择删除
void SLErase(SL* ps, int pos);
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值