/************************************************************************************
文件名:Seqlist.c
头文件:Seqlist.h
时间: 2013/08/05
作者: Hao
功能:可以复用 带有增 删 改 查 功能的顺序表
难点:1.顺序表中存放的都是 各种数据的地址
2.void *是用来隔离封装用的 保证顺序表结构体只能被特定的函数改变
************************************************************************************/
#include <stdio.h>
#include <malloc.h>
#include "Seqlist.h"
typedef unsigned int TSeqListNode;//这个顺序表中存放的是 各种数据的地址 所以用unsigned int
typedef struct str_SeqList
{
int length;//顺序已用的长度
int capacity;//顺序表的总容量
TSeqListNode* node;//这个指针是用来在顺序表中游走读取数据用的
}TSeqList; //定义描述顺序表的结构体
/************************************************************************************
函数名: Creat_SeqList
函数功能: 创建一个容量为capacity的顺序表
参数: int capacity 创建顺序表中成员的个数 即顺序表容量
返回值: void* ret 如果返回NULL 说明创建顺序表失败
如果返回ret 说明创建顺序表成功 且ret为描述顺序表的结构体
************************************************************************************/
SeqList* Creat_SeqList(int capacity)
{
TSeqList* ret = NULL;
/*进入函数 第一点是先判断传人参数的合法性*/
if(capacity >= 0)
{
/*给顺序表开辟空间*/
ret=(TSeqList* )malloc(sizeof(TSeqList)+sizeof(TSeqListNode)*capacity);
if(NULL!=ret)//空间开辟成功 给描述顺序表的结构体 赋值
{
ret->capacity=capacity;
ret->length=0;
ret->node=(TSeqListNode* )(ret+1);//把真正顺序表的地址赋给 node
}
}
else
{
ret = NULL;
}
return (SeqList*)(ret);
}
/************************************************************************************
函数名: Destroy_SeqList
函数功能: 销毁顺序表 free开辟的内存
参数: void* list 描述顺序表结构体指针
返回值: void
************************************************************************************/
void Destroy_SeqList(SeqList* list)
{
free(list);
}
/************************************************************************************
函数名: Get_Seqlist_Length
函数功能:获得顺序表 现在的大小
函数参数:void* list 描述顺序表结构体指针
函数返回值:int ret 成功返回length
失败返回-1
************************************************************************************/
int Get_Seqlist_Length(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函数参数合法性检测*/
if(NULL != Tlist)
{
ret=Tlist->length;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函数名: Get_Seqlist_Capacity
函数功能:获得顺序表 的容量
函数参数:void* list 描述顺序表结构体指针
函数返回值:int ret 成功返回capacity
失败返回-1
************************************************************************************/
int Get_Seqlist_Capacity(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函数参数合法性检测*/
if(NULL != Tlist)
{
ret = Tlist->capacity;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函数名: Clean_Seqlist_Length
函数功能:清空顺序表 其实就是给length=0;
函数参数:void* list 描述顺序表结构体指针
函数返回值:int ret 成功返回0
失败返回-1
************************************************************************************/
int Clean_Seqlist_Length(SeqList* list)
{
int ret;
TSeqList *Tlist=(TSeqList* )list;
/*函数参数合法性检测*/
if(NULL != Tlist)
{
Tlist->length=0;
ret=0;
}
else
ret=-1;
return ret;
}
/************************************************************************************
函数名: Seqlist_Add
函数功能:顺序表中有length个数据 在下标为pos的位置上 插入数据node 所以pos是从0开始的 length是从1开始的
参数: SeqList* list描述顺序表的结构体地址 SeqListNode* node插入顺序表的数据的地址
int pos插入顺序表的位置 pos的范围是从0(此时在顺序表头部插入)开始 到length(此时就是在顺序尾部插入)
总共是length+1个位置
返回值 : 返回1 说明插入数据成功 返回0 说明插入数据失败
************************************************************************************/
int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos)
{
/*参数合法性检测*/
TSeqList *Tlist=(TSeqList* )list;
int ret = (NULL != list);
int i;
ret=ret && (pos >= 0);
ret=ret && (Tlist->length+1 <= Tlist->capacity); //判断再插入一个数据的时候 length有没有超过 capacity
if(1 == ret)
{
if(pos >= Tlist->length)//如果插入的位置pos比 length大的话 默认把length+1赋值给pos
{
pos = Tlist->length;
}
for(i=Tlist->length;i>pos;i--)
{
Tlist->node[i]=Tlist->node[i-1];
}
Tlist->node[i]=(TSeqListNode)node; //把要插入的地址强制类型转换成 unsigned int*
Tlist->length++;
}
return ret;//返回1 说明插入数据成功 返回0 说明插入数据失败
}
/************************************************************************************
函数名: Get_Node
函数功能:找到顺序表中下标为pos的值
参数: pos插入顺序表的下标 pos的范围是从0到length-1
SeqList* list描述顺序表的结构体地址
返回值: void* ret 找到pos为下标的那个值
如果成功返回pos为下标的那个值 如果失败 返回NULL
************************************************************************************/
SeqListNode* Get_Node(SeqList* list, int pos)
{
TSeqList* Tlist=(TSeqList* )list;
SeqListNode* ret=NULL;
if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )
{
ret=(SeqListNode* )Tlist->node[pos]; //强制类型转换成void*
}
return ret;
}
/************************************************************************************
函数名: Del_Node
函数功能:找到顺序表中下标为pos的值 并且删除它
参数: 删除pos为下标的值 pos的范围是从0到length-1
SeqList* list描述顺序表的结构体地址
返回值: void* ret
如果成功返回pos为下标的那个值 如果失败 返回NULL
************************************************************************************/
SeqListNode* Del_Node(SeqList* list, int pos)
{
TSeqList* Tlist=(TSeqList* )list;
SeqListNode* ret=NULL;
int i;
if( (NULL!=Tlist) && (pos>=0) && (pos<Tlist->length) )
{
ret=(SeqListNode* )Tlist->node[pos];
for(i=pos+1; i<Tlist->length; i++)
{
Tlist->node[i-1]=Tlist->node[i];
}
Tlist->length--;
}
return ret;
}
Seqlist.h:
#ifndef __Seqlist__
#define __Seqlist__
typedef void SeqList; //是用来封装 使顺序表结构体 不被外界改变 只可被Seqlist.c文件中的函数改变
//因为 这些函数 对外的接口 都是void*
typedef void SeqListNode;//SeqList 是用来表示 顺序表的 SeqListNode是用来表示顺序表 中变量的
SeqList* Creat_SeqList(int capacity);
void Destroy_SeqList(SeqList* list);
int Get_Seqlist_Length(SeqList* list);
int Get_Seqlist_Capacity(SeqList* list);
int Clean_Seqlist_Length(SeqList* list);
int Seqlist_Add(SeqList* list, SeqListNode* node ,int pos);
SeqListNode* Get_Node(SeqList* list, int pos);
SeqListNode* Del_Node(SeqList* list, int pos);
#endif
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "Seqlist.h"
int main(int argc, char *argv[])
{
SeqList* My_SeqList = NULL;
int a = 10;
int b = 5;
int c = 3;
int d = 6;
int e = 1;
int *p = NULL;
int i = 0;
My_SeqList = Creat_SeqList(5);
if( NULL != My_SeqList )
{
Seqlist_Add(My_SeqList, &a ,0);
Seqlist_Add(My_SeqList, &b ,0);
Seqlist_Add(My_SeqList, &c ,0);
Seqlist_Add(My_SeqList, &d ,0);
Seqlist_Add(My_SeqList, &e ,0);
for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)
{
p=Get_Node(My_SeqList, i);
printf("%d\n",*p);
}
Del_Node(My_SeqList, 3);
for(i=0; i<Get_Seqlist_Length(My_SeqList); i++)
{
p=Get_Node(My_SeqList, i);
printf("%d\n",*p);
}
}
Clean_Seqlist_Length(My_SeqList);
Destroy_SeqList(My_SeqList);
return 0;
}
test_main.c:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "Seqlist.h"
typedef struct student
{
int student_num;
char name[30];
char sex[20];
int age;
}str;
int main()
{
str* str1;
SeqList* slist=NULL;
int i=0;
int age=0;
slist=Creat_SeqList(50);
if(NULL == slist)
{
printf("malloc error!!!\n");
return -1;
}
for(i=0; i<3; i++)
{
put_student(slist, str1);
}
printf("输入你要删除的年龄:\n");
scanf("%d",&age);
printf("\n");
find_student(slist, str1, age);
get_student(slist, str1);
destroy_student(slist, str1);
Clean_Seqlist_Length(slist);
Destroy_SeqList(slist);
return 0;
}
int put_student(SeqList* slist, str* str1)
{
int num;
int ret=(NULL != str1);
if(1 == ret)
{
ret=ret && Seqlist_Add(slist, (str* )malloc(sizeof(str)*1) ,50);
num = Get_Seqlist_Length(slist);
str1 = (str* )Get_Node(slist, num-1);
printf("请输入学生学号:\n");
scanf("%d",&str1->student_num);
printf("请输入学生姓名:\n");
scanf("%s",str1->name);
printf("请输入学生性别:\n");
scanf("%s",str1->sex);
printf("请输入学生年龄:\n");
scanf("%d",&str1->age);
printf("\n");
}
else
{
ret = 0;
}
return ret;
}
int get_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
printf("学生学号:%d\n",str1->student_num);
printf("学生姓名:%s\n",str1->name);
printf("学生性别:%s\n",str1->sex);
printf("学生年龄:%d\n",str1->age);
}
}
else
{
ret = 0;
}
return ret;
}
int destroy_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
free(str1);
}
}
else
{
ret = 0;
}
return ret;
}
int find_student(SeqList* slist, str* str1, int age)
{
int ret=(NULL != str1);
int i=0;
int num=0;
if(1 == ret)
{
num=Get_Seqlist_Length(slist);
for(i=0; i<num; i++)
{
str1 = (str*)Get_Node(slist, i);
if(str1->age == age)
{
Del_Node(slist, i);
num=Get_Seqlist_Length(slist);
i--;
}
}
}
else
{
ret = 0;
}
return ret;
}
test_main.c:
#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include "Seqlist.h"
typedef struct student
{
int student_num;
char name[30];
char sex[20];
int age;
}str;
int main()
{
str* str1;
SeqList* slist=NULL;
int i=0;
int age=0;
slist=Creat_SeqList(50);
if(NULL == slist)
{
printf("malloc error!!!\n");
return -1;
}
for(i=0; i<3; i++)
{
put_student(slist, str1);
}
printf("输入你要删除的年龄:\n");
scanf("%d",&age);
printf("\n");
find_student(slist, str1, age);
get_student(slist, str1);
destroy_student(slist, str1);
Clean_Seqlist_Length(slist);
Destroy_SeqList(slist);
return 0;
}
int put_student(SeqList* slist, str* str1)
{
int num;
int ret=(NULL != str1);
if(1 == ret)
{
ret=ret && Seqlist_Add(slist, (str* )malloc(sizeof(str)*1) ,50);
num = Get_Seqlist_Length(slist);
str1 = (str* )Get_Node(slist, num-1);
printf("请输入学生学号:\n");
scanf("%d",&str1->student_num);
printf("请输入学生姓名:\n");
scanf("%s",str1->name);
printf("请输入学生性别:\n");
scanf("%s",str1->sex);
printf("请输入学生年龄:\n");
scanf("%d",&str1->age);
printf("\n");
}
else
{
ret = 0;
}
return ret;
}
int get_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
printf("学生学号:%d\n",str1->student_num);
printf("学生姓名:%s\n",str1->name);
printf("学生性别:%s\n",str1->sex);
printf("学生年龄:%d\n",str1->age);
}
}
else
{
ret = 0;
}
return ret;
}
int destroy_student(SeqList* slist, str* str1)
{
int ret=(NULL != str1);
int i=0;
if(1 == ret)
{
for(i=0; i<Get_Seqlist_Length(slist); i++)
{
str1 = (str*)Get_Node(slist, i);
free(str1);
}
}
else
{
ret = 0;
}
return ret;
}
int find_student(SeqList* slist, str* str1, int age)
{
int ret=(NULL != str1);
int i=0;
int num=0;
if(1 == ret)
{
num=Get_Seqlist_Length(slist);
for(i=0; i<num; i++)
{
str1 = (str*)Get_Node(slist, i);
if(str1->age == age)
{
Del_Node(slist, i);
num=Get_Seqlist_Length(slist);
i--;
}
}
}
else
{
ret = 0;
}
return ret;
}