数据结构--顺序表及其实现
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数据结构单链表接口函数逻辑解析与代码实现(含详细代码注释)