静态顺序表的定义

顺序表是在计算机内存中以数组的形式保存的线性表,线性表的顺序存储是指用一组地址连续的存储单元依次存储线性表中的各个元素、使得线性表中在逻辑结构上相邻的数据元素存储在相邻的物理存储单元中,即通过数据元素物理存储的相邻关系来反映数据元素之间逻辑上的相邻关系,采用顺序存储结构的线性表通常称为顺序表。顺序表是将表中的结点依次存放在计算机内存中一组地址连续的存储单元中。

首先写好.h头文件

#ifndef _SEQ_TABLE_H__
#define _SEQ_TABLE_H__

#include 
#include 
#include 
#include 
#define SUCCESS 0
#define FAILURE -1

typedef int ElemType;

#define STSIZE sizeof(struct SeqTable)

//顺序表
struct SeqTable{
	ElemType* elems;  //使用动态内存 申请内存空间 
 	size_t size;	//元素的个数 _size 
	size_t cap;		//顺序表的容量 _cap 
}; 

//ST  就相当于   struct SeqTable *
typedef struct SeqTable *ST;

//创建一个指定容量的顺序表    分配内存空间  fopen 
ST create_seqtable(size_t cap); 
// ST st= create_seqtable(10);

//初始化顺序表
//int init_seqtable(ST st,size_t cap); 
//struct SeqTable st;
//init_seqtable(&st,10);

//销毁顺序表  释放内存空间  fclose 
void destroy_seqtable(ST st);

//静态顺序表 不能扩容   是否已满
bool full_seqtable(ST st);

//顺序表是否为空 
bool empty_seqtable(ST st); 

//顺序表中元素个数 
size_t size_seqtable(ST st);

//顺序表的容量 
size_t capcity_seqtable(ST st);

//为什么只提供在末尾插入和删除的特定接口 push_back pop_back
//顺序表在末尾插入和删除效率高  在front插入和删除效率最低(不会额外提供特殊的接口),只能使用通用的insert/remove 

//在顺序表末尾添加一个元素e   返回值表示插入是否成功 
int push_back_seqtable(ST st,ElemType e);

//在指定位置pos(下标)插入一个元素e
int insert_seqtable(ST st,size_t pos,ElemType e) ;

//删除指定位置的元素
int remove_seqtable(ST st,size_t pos,ElemType *pe); 

//删除最后一个位置的元素 
int pop_back_seqtable(ST st,ElemType *pe); 

//删除所有值等于e的元素 
int delete_all_seqtable(ST st,ElemType e); 

//删除第n个值等于e的元素
int delete_count_seqtable(ST st,ElemType e,size_t n); 

//修改  更新 
int update_seqtable(ST st,size_t pos,ElemType ne); 

//索引 根据位置获取对应的元素
ElemType *elem_of_seqtable(ST st,size_t pos); 

//查找 查找第n个元素e,返回其下标位置 
int find_seqtable(ST st,ElemType e,size_t n);

//统计e在顺序表元素的个数 
size_t count_seqtable(ST st,ElemType e);

//查找 根据条件查找第n个满足条件的元素 
int search_seqtable(ST st,bool (*condition)(ElemType *pe),size_t n);

//迭代
void foreach_seqtable(ST st,void (*foreach)(ElemType *pe)); 

//清空
void clear_seqtable(ST st);


#endif//_SEQ_TABLE_H__

在.c文件中完成各个函数的目的

#include "seqtable.h"

//创建一个指定容量的顺序表    分配内存空间  fopen 
//返回NULL 失败 如果成功返回顺序表的内存地址 
ST create_seqtable(size_t cap)
{
	ST st =(ST)malloc(STSIZE);  //申请struct SeqTable结构体的内存地址 
	if(st !=NULL){
		st->cap=cap;
		st->size=0;
		st->elems=(ElemType*)calloc(cap,sizeof(ElemType));
		if(st->elems==NULL){
			free(st);
			st=NULL;
		}
	} 
	return st;
}
// ST st= create_seqtable(10);

//初始化顺序表
//int init_seqtable(ST st,size_t cap); 
//struct SeqTable st;
//init_seqtable(&st,10);

//销毁顺序表  释放内存空间  fclose 
void destroy_seqtable(ST st)
{
	assert(st!=NULL);
	free(st->elems);
	free(st);
}


//静态顺序表 不能扩容   是否已满
bool full_seqtable(ST st)
{
	assert(st!=NULL);
	return st->size ==st->cap;
}
//顺序表是否为空 
bool empty_seqtable(ST st)
{
 	assert(st!=NULL);
 	return st->size==0;
}
//顺序表中元素个数 
size_t size_seqtable(ST st)
{
	assert(st!=NULL);
	return st->size;
}
//顺序表的容量 
size_t capcity_seqtable(ST st)
{
	assert(st!=NULL);
	return st->cap;
}

//为什么只提供在末尾插入和删除的特定接口 push_back pop_back
//顺序表在末尾插入和删除效率高  在front插入和删除效率最低(不会额外提供特殊的接口),只能使用通用的insert/remove 

//在顺序表末尾添加一个元素e   返回值表示插入是否成功 
int push_back_seqtable(ST st,ElemType e)
{
	assert(st!=NULL);
	if(full_seqtable(st)){
		return FAILURE;
	}
	st->elems[st->size]=e;
	st->size++;
	return SUCCESS;
}

//在指定位置pos(下标)插入一个元素e
int insert_seqtable(ST st,size_t pos,ElemType e)
{
	assert(st!=NULL);
	if(full_seqtable(st)||pos>st->size){
			return FAILURE;
		}
	for(int i=st->size;i>pos;i--){
			st->elems[i]=st->elems[i-1];
		}	
	/*for(int i=st->size-1;i>=(int)pos;i--){
		st->elems[i+1]=st->elems[i];  这里pos需要强转 不然int类型-1大于size_t的数 
	}*/
	st->elems[pos]=e;
	st->size++;
	return SUCCESS;
}

//删除指定位置的元素
int remove_seqtable(ST st,size_t pos,ElemType *pe)
{
	assert(st!=NULL);
	if(pos>=st->size) 
	{
		return FAILURE;
	}
	if(pe !=NULL){
		*pe = st->elems[pos]; //保存删去的元素 
	}
	for(int i=pos+1;isize;++i)
	{
		st->elems[i-1]=st->elems[i];
	}
	st->size--;
	return SUCCESS;
}

//删除最后一个位置的元素 
int pop_back_seqtable(ST st,ElemType *pe)
{
	assert(st!=NULL);
	if(empty_seqtable(st)){
		return SUCCESS;
	}
	--st->size;
	if(pe!=NULL){
		*pe =st->elems[st->size];
	}
	return SUCCESS;
}

//删除所有值等于e的元素 
int delete_all_seqtable(ST st,ElemType e)
{
	assert(st!=NULL);
	int cnt =0;//返回值 删除的个数 
	for(int i=0;isize;i++){
		if(st->elems[i]==e){
			remove_seqtable(st,i,NULL); //定义过的删除函数
			++cnt;
			--i;//防止连续出现e,而无法完全删除 
		}
	}
	return cnt;
}
//删除第n个值等于e的元素
int delete_count_seqtable(ST st,ElemType e,size_t n)
{
	assert(st!=NULL&& n!=0);
		for(int i=0;isize;i++){
			if(st->elems[i]=e){
				--n;
				if(n==0){
					return remove_seqtable(st,i,NULL);
				}
			}
		}
	return FAILURE;	
}

//修改  更新 
int update_seqtable(ST st,size_t pos,ElemType ne)
{
	assert(st!=NULL);
	if(pos>=st->size){
		return FAILURE;
	}
	st->elems[pos]=ne;
	return SUCCESS;
} 

//索引 根据位置获取对应的元素
ElemType *elem_of_seqtable(ST st,size_t pos)
{
	assert(st!=NULL);
	if(pos>=st->size)
	{
		return NULL;
	}
	return &st->elems[pos]; //返回地址 
}
//查找 查找是否存在某个元素e
int find_seqtable(ST st,ElemType e,size_t n)
{
	assert(st!=NULL&&n!=0);
	int i;
	for(i=0;isize;++i)
	{
		if(st->elems[i]==e){
			if(--n==0)
			return i;
		}
	}
	return -1;
}

//统计e在顺序表元素的个数 
size_t count_seqtable(ST st,ElemType e)
{
	assert(st!=NULL);
	int i;
	size_t cnt=0;
	for(i=0;isize;++i)
	{
		if(st->elems[i]==e)
		{
			++cnt;
		}
	}
	return cnt;
}


//查找 根据条件查找第n个满足条件的元素 
int search_seqtable(ST st,bool (*condition)(ElemType *pe),size_t n)
{
	assert(st!=NULL&&condition!=NULL&&n!=0);
	int i;
	for(i=0;isize;++i)
	{
		if(condition(&st->elems[i]))
		{
			if(--n==0){
				return i;
			}
		}
	}
	return -1;
}

//迭代
void foreach_seqtable(ST st,void (*foreach)(ElemType *pe))
{
	assert(st!=NULL&&foreach!=NULL);
	int i;
	for(i=0;isize;i++){
		foreach(&st->elems[i]);
	}
} 

//清空 
void clear_seqtable(ST st)
{
	assert(st!=NULL);
	st->size=0;
}

对于顺序表的使用方法,还是得再多看看。如果有错误 欢迎指正!

你可能感兴趣的:(c语言)