《数据结构学习笔记---第二篇》---顺序表

目录

1.线性表

2.顺序表

2.1概念及结构

3.具体实现

3.1创建头文件“Seqlist.h”

3.2创建具体接口实现文件Seqlist.h

3.2.1打印

3.2.2检查容量并扩容

3.2.3初始化

 3.2.4尾插尾删

3.2.6寻找x元素,找到其下标

3.2.7按位置插入删除

3.2.8销毁顺序表

4.主函数的实现


1.线性表

线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串...

线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的, 线性表在物理上存储时,通常以数组和链式结构的形存储。

2.顺序表

2.1概念及结构

顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存 储。在数组上完成数据的增删查改。 顺序表一般可以分为:

1. 静态顺序表:使用定长数组存储元素。

2.动态顺序表:使用动态开辟的数组存储

3.具体实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空 间开多了浪费,开少了不够用。所以现实中基本都是使用动态顺序表,根据需要动态的分配空间 大小,所以下面我们实现动态顺序表。

3.1创建头文件“Seqlist.h”

  ​​​​​为什么要创立头文件

#pragma once  //防止重复包含
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>

typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;//传的是数组下标的指针,用形参真正的改变到实参
	int size;      //记录有效数据个数
	int capicity;   //记录容量
}SL;

void SLCheckCapacity(SL* ps);
//检查容量
void SLPrint(SL* ps);
//打印
void SLInit(SL* ps);
//初始化
void SLDestroy(SL* ps);
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);
//尾插尾删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);
//头插头删
int SeqListFind(SL* ps, SLDataType x);
//寻找x元素,找到其下标
void SLErase(SL* ps, int pos);
void SLInsert(SL* ps, int pos, SLDataType x);
//按位置插入删除

3.2创建具体接口实现文件Seqlist.h

先引用#include "SeqList.h"

3.2.1打印

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

 在这里我们用了断言assert,如果头指针为空指针,程序就会报错。

3.2.2检查容量并扩容

void SLCheckCapacity(SL* ps)
{
	assert(ps);
	if (ps->size == ps->capicity)
	{
		int newCapicity = ps->capicity == 0 ? 4 : ps->capicity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newCapicity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			perror("relloc fail");
			exit(-1);
		}
		ps->a = tmp;
		ps->capicity = newCapicity;
	}
}

 在这里我们用了扩容,但我们使用的是异地realloc而不是malloc,这是由于我们可能初始申请的空间不足,方便后续扩容且节省空间。关于更多realloc,malloc

3.2.3初始化

void SLInit(SL* ps)

{
	assert(ps);
	ps->a = NULL;//未定义的原因是 没有头文件#include "string.h"
	ps->size = 0;
	ps->capicity = 0;
}

 3.2.4尾插尾删

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

void SLPopBack(SL* ps)
{
	assert(ps);
	/*int* tmp = ps->size--;
	free(ps->size);*/
	if (ps->size > 0)
	{
		ps->size--;
	}
}

3.2.5头插头删

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

void SLPopFront(SL* ps)
{
	assert(ps);
	for(int i = 0; i<ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

3.2.6寻找x元素,找到其下标

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

3.2.7按位置插入删除

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

}

3.2.8销毁顺序表

void SLDestroy(SL* ps)
{
	/*assert(ps);*/ //这里可以直接用if
	if (ps->a)
	{
		free(ps->a);
		ps->a = NULL;
		ps->size = 0;
		ps->capicity = 0;
	}

}

4.主函数的实现

#include "SeqList.h"

void TestSeqList1()
{
	SL sl;
	SLInit(&sl);
	//尾插测试
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(&sl);
	//头插测试
	SLPushFront(&sl, 100);
	SLPushFront(&sl, 200);
	SLPushFront(&sl, 300);
	SLPrint(&sl);
	//头删测试
	SLPopFront(&sl);
	SLPopFront(&sl);
	SLPrint(&sl);

	SLPrint(&sl);
	SLInsert(&sl, 2, 666);
    SLPrint(&sl);
	SLErase(&sl, 4);
	SLPrint(&sl);
}


int main() // 1.先写主函数
{
	TestSeqList1();


	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值