数据结构--顺序表及其实现

Posted 水澹澹兮生烟.

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了数据结构--顺序表及其实现相关的知识,希望对你有一定的参考价值。

1.顺序表的基本内容

顺序表属于线性表中的一种,他是用一段物理地址连续的存储单元一次存储数据元素的线性结构,一般情况下采用数组。顺序表可分为:
a.静态顺序表:使用定长数组存储;
b.动态顺序表:使用动态开辟的数组存储。

2.顺序表的实现

在实现顺序表时,静态表只适用于确定的数据的场景。空间的开辟的大小选择因此会困难。下面是实现动态顺序表。
a. SeqList.h文件

//顺序表中所要实现方法包括
#pragma once
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
typedef int DataType;
typedef struct SeqList{//定义结构体变量
	DataType* a;//顺序表里面的数据
	size_t size;//顺序表里有效元素的个数
	size_t capacity;//标记空间总的大小
}SeqList;
void SeqList_Print(SeqList* ps);// 对顺序表进行打印
void SeqList_Init(SeqList* ps, int initCap);// 对顺序表进行初始化
void SeqList_Destory(SeqList* ps);//对顺序表内容进行销毁
void SeqList_PushBack(SeqList* ps, DataType x);//在顺序表中进行尾插
void SeqList_PopBack(SeqList* ps);//在顺序表中进行尾删
int SeqList_Empty(SeqList* ps);//检测顺序表是否为空
int SeqList_Size(SeqList* ps);//获取有效的元素个数
int SeqList_capacity(SeqList* ps);//获取顺序表中的总容量--底层空间的大小
void SeqList_PushFront(SeqList*ps, DataType x);//顺序表中进行头插
int SeqList_Find(SeqList* ps, DataType x);//顺序表查找
void SeqList_Insert(SeqList* ps, size_t pos, DataType x);//顺序表在pos位置处插入
void SeqList_Erase(SeqList* ps, size_t pos);//在pos的位置进行删除
void SeqList_Reserve(SeqList* ps,int capcity);//将顺序表中的容量扩增到capcity

b. SeqList_op.c文件
在这个文件里面,我们实现了上述所需的所有操作:

#include"SeqList.h"
#include<stdio.h>
#include<assert.h>
#include<malloc.h>

void SeqList_Print(SeqList* ps)// 对顺序表进行打印
{
	assert(ps != NULL);
	for (int i = 0; i < (ps->size); i++){
		printf("%d   ", ps->a[i]);
	}
	printf("\\n");
}
void SeqList_Init(SeqList* ps, int initCap){// 对顺序表进行初始化
	assert(ps != NULL);
	//1.申请空间  2.将容量以及有效元素设置好
	ps->a = (DataType*)malloc(initCap*sizeof(DataType));//malloc在堆上申请空间,如果申请不成功,则返回NULL
	if (NULL == ps->a){
		assert(0);
		return;
	}
	ps->capacity = initCap;
	ps->size = 0;//初始化时有效元素为0个
}
void SeqList_Destory(SeqList* ps)//对顺序表内容进行销毁
{
	assert(ps != NULL);
	if (ps->a == NULL){
		assert(0);
		return;
	}
	free(ps->a);
	ps->a = NULL;
	ps->capacity = 0;
	ps->size = 0;
}
void SeqList_PushBack(SeqList* ps, DataType x)//在顺序表中进行尾插
{
	assert(ps != NULL);
	if (ps->size < ps->capacity){
		ps->a[ps->size++] = x;
	}
	else{
		return;
	}
}
void SeqList_PopBack(SeqList* ps)//在顺序表中进行尾删
{
	assert(ps != NULL);
	if (SeqList_Empty(ps)){//ps->size == 0 ;在这里可以直接调用这个函数
		return;
	}
	else
		ps->size--;
}
int SeqList_Empty(SeqList* ps)//检测顺序表是否为空
{
	assert(ps != NULL);
	return 0 == ps->size;
}
int SeqList_Size(SeqList* ps){//获取有效的元素个数
	assert(ps != NULL);
	return ps->size;
}
int SeqList_capacity(SeqList* ps){
	assert(ps->size);
	return ps->capacity;
}
void SeqList_PushFront(SeqList*ps, DataType x){
	assert(ps != NULL);
	int i = ps->size;
	if (SeqList_Empty(ps)) ps->a[0] = x;
	else{
		while (i){
			ps->a[i] = ps->a[i-1];
			i--;
		}
		ps->a[i] = x;
	}
	ps->size++;
}
int SeqList_Find(SeqList* ps, DataType x){
	int count = 0;
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x){
			return i;
			count++;
			break;
		}
	}
	if (0 == count) return -1;
}
void SeqList_Insert(SeqList* ps, size_t pos, DataType x){
	//检测空间是否足够,不够的话要进行扩容,但边插入便扩容效率会低,所以在main中直接调用扩容函数

	assert(ps != NULL);
	//插入  1.将pos及其后面的元素往后搬移
	//2.在pos位置进行插入
	if (pos>=0&&pos<=ps->size)
	{
		for (int i = ps->size; i > pos; --i){//要控制好边界
			ps->a[i] = ps->a[i - 1];
		}
		ps->a[pos] = x;
	}
	else{
		printf("所给位置非法!!!\\n");
		return;
	}
	ps->size++;
}
/*
for(int i=ps->size;i>pos;--i)
{ps->a[i]=ps->a[i-1];}
*/
void SeqListErase(SeqList* ps, size_t pos){
	assert(ps != NULL);


	//删除pos位置上的数,1.先进行判断   2.直接将pos位置后的数向前进行搬移
	if (pos<0 || pos>ps->size){
		printf("所给位置非法!!!\\n");
		return;
	}
	else
	{
		for (int i = pos+1; i < ps->size; i++){
			ps->a[i - 1] = ps->a[i];
		}
	}
	ps->size--;
}
void SeqList_Reserve(SeqList* ps, int capcity){//容量用可能增大,也有可能减小
	assert(ps!=NULL);
	if (capcity <= ps->capacity) return;
	//扩容 1.申请新空间  2.拷贝元素 3.释放就空间 4.返回新空间
	//但是在这里使用realloc,代码是有点问题的!!!!现在还没有搞清楚,之后再补上,嘿嘿
	ps->a = (DataType*)realloc(ps->a, capcity*sizeof(DataType));
	assert(ps->a);
	ps->capacity = capcity;
}

c. test.c文件

#include<stdio.h>
#include"SeqList.h"
int main(){
	SeqList pa;
	SeqList_Init(&pa, 6);
	SeqList_PushFront(&pa, 1);
	SeqList_PushFront(&pa, 2);
	SeqList_PushFront(&pa, 3);
	SeqList_PushBack(&pa, 4);
	SeqList_PushBack(&pa, 5);
	printf("size=%d\\n", SeqList_Size(&pa));
	printf("capacity=%d\\n", SeqList_capacity(&pa));
	SeqList_Print(&pa);
	printf("pos插入后的a:\\n");
	SeqList_Insert(&pa,3,3);
	printf("size=%d\\n", SeqList_Size(&pa));
	printf("capacity=%d\\n", SeqList_capacity(&pa));
	SeqList_Print(&pa);
	printf("查找2的位置:the site =%d\\n", SeqList_Find(&pa, 2));
	printf("进行两次尾删后的a:\\n");
	SeqList_PopBack(&pa);
	SeqList_PopBack(&pa);
	printf("size=%d\\n", SeqList_Size(&pa));
	printf("capacity=%d\\n", SeqList_capacity(&pa));
	SeqList_Print(&pa);
	printf("在pos处删除后的a:\\n");
	SeqListErase(&pa,2);
	printf("size=%d\\n", SeqList_Size(&pa));
	printf("capacity=%d\\n", SeqList_capacity(&pa));
	SeqList_Print(&pa);
	SeqList_Reserve(&pa, 12);
	printf("capacity=%d\\n", SeqList_capacity(&pa));
}

代码测试结果:
在这里插入图片描述

以上是关于数据结构--顺序表及其实现的主要内容,如果未能解决你的问题,请参考以下文章

数据结构--顺序表及其实现

数据结构之顺序表的插入删除操作(静态分配实现)及其时间复杂度分析

C数据结构单链表接口函数逻辑解析与代码实现(含详细代码注释)

(王道408考研数据结构)第七章查找-第二节1:顺序查找及其优化

Java数据结构学习笔记之一线性表的存储结构及其代码实现

数据结构——顺序表及其操作