动态顺序表

发布时间:2024年01月17日

一、说明

1.什么是数据结构?
??这个简单理解,数据结构就是存储数据的结构,数据用怎样形式来存储,就考虑实现怎样的结构!!!
2.什么是线性表?
??线性表就是在逻辑上是按一条线的形式存储,而在物理空间或者真正的内存中可能不是线性的,这个,有些因素不可控,比如:数组就是在逻辑和物理空间上都是线性的,而顺序表是malloc的堆区的空间,是不知道空间是连续的还是怎样的!

二、顺序表

1.我觉得在学习顺序表这种的数据结构的时候,首先把大框架弄好,到底是怎样的存储形式,怎么组织,把大框架弄好,然后一点一点写代码就不会出错!(虽然这个结构很简单,但是一步步调试,能更好的学习数据结构)
2.先给出静态顺序表的结构!(还是写一下)对于静态顺序表较简单,只写尾插,头插,尾删,头删,打印数据,这几个接口。
1
??上面这种结构就很清楚了,那么怎么存储数据呢?首先要在栈区开辟一个结构体,这个结构体是干嘛的呢?很简单,在这个结构体中,有一个元素是数组,用来存储数组,有一个变量,用来存储有效数据的个数,那么,可以发现,静态顺序表是一个物理和逻辑上都是线性的顺序表。
3.那么该如何实现?
??很简单,首先应该创建一个结构体,然后在结构体的一个元素数组中存数据,然后统计数据的有效个数,再后来,怎么操作,就按需求来写了,下面我大概写了几个接口!!!``

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

/****************SeqList.h**************/
//静态顺序表结构

typedef int SLDataType;
#define N 7

typedef struct SeqList
{
	SLDataType arr[N];  //数据存储数据
	int size;           //有效元素的个数
}SL;


//写几个接口
void StiSLInit(SL* ps);

void StiSLPushBack(SL* ps, SLDataType x);
void StiSLPushFront(SL* ps, SLDataType x);
void StiSLPopBack(SL* ps);
void StiSLPopFront(SL* ps);

void StiSLPrint(SL sl);
/*****************SeqList.c*******************/
#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

//写几个接口
void StiSLInit(SL* ps)
{
	//不能传空地址
	assert(ps);
	ps->size = 0;  //没有有效数据,初始化为0
	//ps->arr;     //是静态的数组,arr的空间大小是定值
}

void StiSLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//考虑数组的大小
	if (ps->size <= N) //至少要有一个元素放得下
	{
		ps->arr[ps->size] = x;
		ps->size++;
	}
}
void StiSLPushFront(SL* ps, SLDataType x)
{
	assert(ps);
	if (ps->size < N+1)
	{
		for (int i = (ps->size) - 1; i >= 0; i--)
		{
			ps->arr[i + 1] = ps->arr[i];
		}
		ps->arr[0] = x;
		ps->size++;
	}
}
void StiSLPopBack(SL* ps)
{
	assert(ps);
	if ((ps->size) > 0)
	{
		ps->size--;
	}
}
void StiSLPopFront(SL* ps)
{
	assert(ps);
	if ((ps->size) > 0)
	{
		for (int i = 0; i < (ps->size)-1; i++)
		{
			ps->arr[i] = ps->arr[i + 1];
		}
		ps->size--;
	}
}

void StiSLPrint(SL sl)
{
	for (int i = 0; i < sl.size; i++)
	{
		printf("%d ", (sl.arr)[i]);
	}
	printf("\n");
}
/**********Test.c************************/
#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void SticSeqListTest()
{
	//在栈区为结构体开辟空间
	SL sl;
	StiSLInit(&sl);
	StiSLPushBack(&sl, 1);
	StiSLPushBack(&sl, 2);
	StiSLPushBack(&sl, 3);
	StiSLPushBack(&sl, 4);
	StiSLPrint(sl);
	StiSLPushFront(&sl, 0);
	StiSLPrint(sl);
	StiSLPopBack(&sl);
	StiSLPrint(sl);
	StiSLPopFront(&sl);
	StiSLPrint(sl);
}
int main()
{
	SticSeqListTest();
	return 0;
}

三、动态顺序表

1
1、动态顺序表的实现也不是很难,先想一下怎么实现,既然是动态,就要能动态开辟空间,就要malloc动态开辟,还要记录开辟的空间是多少?存的数据个数是多少,那么,有一个结构体,定义一个指针,以这个指针指向来开辟空间,然后在开辟的这个空间内放数据,在记录有效数据,看看是否空间满足,后面就根据自己的需求写代码!!!

/****************SeqList.h************/
#define  _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//静态顺序表

#define N 100
typedef int SLDataType;

//struct SeqList
//{
//  SLDataType a[N];
//  int size;
//};

typedef struct SeqList
{
	SLDataType* arr;
	int capacity;
	int size;
}SL;

void SLInit(SL* ps);
void SLDestroy(SL* ps);

void SLPushBack(SL* ps, SLDataType x);
void SLPushFront(SL* ps, SLDataType x);

void SLPopBack(SL* ps);
void SLPopFront(SL* ps);
void SLPrint(SL sl);

//在pos前插入
void SLInsert(SL* ps, int pos, int x);

//删除pos位置
void SLErase(SL* ps, int pos);
/*************SeqList.c******************/
#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

void CheckCapacity(SL* ps)
{
	if (ps->capacity == ps->size)
	{
		int newcapacity = ps->capacity == 0 ? 4 : 2 * ps->capacity;
		SLDataType* tmp = (SLDataType*)realloc(ps->arr, sizeof(SLDataType) * newcapacity);
		if (!tmp)
		{
			perror("Realloc fail:");
			return 1;
		}
		ps->arr = tmp;
		ps->capacity = newcapacity;
	}
}

void SLPrint(SL sl)
{
	for (int i = 0; i < sl.size; i++)
	{
		printf("%d ", (sl.arr)[i]);
	}
	printf("\n");
}
void SLInit(SL* ps)
{
	ps->arr = NULL;
	ps->capacity = ps->size = 0;
}

void SLPushBack(SL* ps, SLDataType x)
{
	assert(ps);
	//空间不够,扩容
	CheckCapacity(ps);
	//空间足够,直接插入
	ps->arr[ps->size++] = x;

}

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

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

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

//在pos前插入
void SLInsert(SL* ps, int pos, int x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	//[0,pos)位置不移动,[pos,ps->size-1]位置向后移动一位
	for (int i = (ps->size) - 1; i > pos; i--)
	{
		(ps->arr)[i + 1] = (ps->arr)[i];
	}
	(ps->arr)[pos] = x;
	ps->size++;
}

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

void SLDestroy(SL* ps)
{
	assert(ps);
	free(ps->arr);
	ps->arr = NULL;
}
/*************Test.c**********************/
#define  _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"


void slTest01()
{
	SL sl;
	SLInit(&sl);
	SLPushBack(&sl, 1);
	SLPushBack(&sl, 2);
	SLPushBack(&sl, 3);
	SLPushBack(&sl, 4);
	SLPushBack(&sl, 5);
	SLPrint(sl);
	SLPushFront(&sl, 0);
	SLPushFront(&sl, -1);
	SLPrint(sl);
	SLPopBack(&sl);
	SLPopBack(&sl);
	SLPrint(sl);
	SLPopFront(&sl);
	SLPopFront(&sl);
	SLPrint(sl);
	SLInsert(&sl, 0, 0);
	SLPrint(sl);
	SLInsert(&sl, 3, 4);
	SLPrint(sl);
	SLDestroy(&sl);
}
int main()
{
	slTest01();
	return 0;
}

完结!!!

文章来源:https://blog.csdn.net/2301_76821799/article/details/135649699
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。