顺序表之线性表(难度:✨)

1.线性表

线性表呈现出一条线性,用指针把一块一块的内存连接起来。
其余还有树型结构,哈希结构,图结构。
线性表分为:

  • 顺序表
  • 链表
  • 队列
  • 字符串

1.2顺序表

顺序表就是数组,但在数组的基础上,从头开始存。还要求数据连续存储,不能跳跃间隔。
本质:数组(分为静态和动态)
(顺序表要求连续存储,数据挨着存)

写相对正式的代码要规范。
宏或条件编译,防止头文件被重复包含。
不仅仅有数组,还要用size标识有多少数组
凡是多个数组,都用结构体
完善:

  1. 对顺序表初始化一下
  2. 尾插,头插
    .h放声明
    .cpp放定义
//建立一个头文件SeqList.h,用静态顺序表实现
#pragma once
#define N 1000
//宏的好处让静态的数据表随时转换
//静态顺序表结构
typedef int SLDataType;//想存什么类型就改中间的字母
//想让顺序表存储管理别的东西
//为了一个地方改其他地方都改,定义一个typedef
typedef struct SeqList//结构体typedef
{
	SLDataDype a[N];
	//最简单的应该有个数组(定义成静态)
	//不推荐在这里直接写数字,因为换大小不好换
	int size;
	//表示数组中存储了多少个有效数据,从头连续存储

}SL;//简写
//向顺序表中插入数据
//对顺序表初始化
//接口函数,给别人用的,对接。--命名风格跟STL走,方便后续学习STL
void SeqListInit( SL* ps);
//尾插数据
void SeqListPushBack( SL* ps, SLDataType x);//用SLDataType做这个地方的类型
//结构体SeqList太长,可typedef一下,变成SL
//尾删
void SeqListPopBack( SL* ps);
//头插
void SeqListPushFront( SL* ps, SLDataType x);
//头删
void SeqListPopFront( SL* ps);

静态顺序表

  1. 特点:满了不让插入
  2. 缺点:给多大的空间很难确定n给小不够用,n给大了浪费。

动态顺序表

#pragma once
typedef int SLDataType;
typedef struct SeqList
{
	SLDataType* a;//定义成指针
	int size;
	//表示数组中存储了多少个有效数据,从头连续存储
	//提供动态开辟内存的方式malloc,在堆上可以动态开辟内存,不用了可以释放。
	//最后不够了把原来的空间释放,开更大的一块空间。叫做扩容。
	//现在的结构不足以方便地表示动态顺序表。有一个指针,指向动态开辟的空间。
	//增加capacity即容量。表示数组实际能存的空间容量多大。多少个数据
	int capacity;
	}SL;

SeqList.c

#include "SeqList.h"
#include 
#include 
//初始化
void SeqListInit(SL ps)
{
	//应该用.因为a是成员
	ps.a = NULL;
	ps.size = ps.capacity = 0;
	//最开始对顺序表的初始化
}
//尾插数据
void SeqListPushBack(SL* ps, SLDataType x);//用SLDataType做这个地方的类型
//结构体SeqList太长,可typedef一下,变成SL
//尾删
void SeqListPopBack(SL* ps);
//头插
void SeqListPushFront(SL* ps, SLDataType x);
//头删
void SeqListPopFront(SL* ps);

Test.c

#include "SeqList.h"
//调用函数
void TestSeqList1()
{
	SL sl;
//sl未初始化
	SeqListInit(sl);//对结构体进行初始化
}
int main()
{
	TestSeqList1();
	return 0;
}

错误的!!!
sl:实参
ps:形参
实参传给形参。ps形参改变不影响实参
用实参的地址,应该传指针
修改:
void SeqListInit(SL* ps);
ps->a = NULL;
ps->size = ps->capacity = 0;
SeqListInit(&sl);

尾插数据


void SeqListPushBack(SL* ps, SLDataType x)//用SLDataType做这个地方的类型
{
	//整个顺序表没有空间
	//刚进来只对其进行初始化没有空间
	//如果没有空间或空间不足就扩容
	if (ps->size == ps->capacity)
		//第二种情况:capacity空间满了,扩容realloc,对已有的空间扩容
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity;
		//如果=0给四。不是零增2倍
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapacity * sizeof(SLDataType));//不应给数据个数,应给字节个数
			if (tmp == NULL)
			{
				printf("realloc fail\n");
				exit(-1);
		    }
		ps->a = tmp;
		ps->capacity = newcapacity;

	
	}
	ps->a[ps->size] = x;
	ps->size++;//空间足够
}

return -1:不可以,没有终止掉程序
exit(-1):结束掉程序,异常退出返回-1,正常返回0
动态顺序表:
//顺序表的动态存储

typedef struct SeqList
{
SLDataType* array;//指向动态开辟的数组
size_t size;//有效数据个数
size_t capacity;//容量空间的大小
}SeqList;

调试按Fn+F11
顺序表之线性表(难度:✨)_第1张图片
顺序表之线性表(难度:✨)_第2张图片

SeqList.c

void SeqListPrint(SL* ps)//把顺序表中的打印
{
	for (int i = 0; i < ps->size; ++i)
	{
		printf("%d ", ps->a[i]);
	}
	printf("\n");
}

Test.c

SeqListPrint(&sl);

顺序表之线性表(难度:✨)_第3张图片

插入数据不用以后空间需要销毁。

//销毁顺序表
void SeqListDestory(SL* ps);
//销毁顺序表
void SeqListDestory(SL* ps);
{
	free(ps->a);
	ps->a = NULL;
	ps->capacity = ps->size = 0;
}
//把空间还给系统
 SeqListDestory(&SL);

继续写尾删,想把尾上的数据删除

typedef struct SeqList
{
 SLDataType* a;
 int size;//插入了两个数据
 int capacity;//可以存几个数据
 }SL;

把尾上的数置成零,再把size–

void SeqListPopBack(SL* ps)
{
	//ps->a[ps->size - 1] = 0;//把数置成0
	ps->size--;//原来是2,后来减到1.
}

size标识存了制了多少有效数据

SeqListPopBack(&sl);
	SeqListPopBack(&sl);
	//删除两个数据后再打印
	SeqListPrint(&sl);

顺序表之线性表(难度:✨)_第4张图片
为防止删除的数据多于原本的数据个数
需加前提条件

void SeqListPopBack(SL* ps)
{
	if (ps->size > 0)
	{
		ps->a[ps->size - 1] = 0;
		ps->size--;//原来是2,后来减到1

	}
}

顺序表之线性表(难度:✨)_第5张图片
粗暴的方式

#include //断言
void SeqListPopBack(SL* ps)
{
	assert(ps->size > 0);
	ps->size--;
}

在这里插入图片描述
在64行断言失败。

你可能感兴趣的:(算法,数据结构,c语言)