我的代码参照了严蔚敏、吴伟民编写的数据结构(C语言版)
所有代码采用C语言编写。讲解请查看注释。
*另注:书中很多函数采用了引用传值,如InitList(Sqlist &L)。但C语言并不支持引用传值,因此统一改为地址传值,即InitList(Sqlist *L)。
头文件及宏定义
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
//线性表动态分配存储结构
#define LIST_INIT_SIZE 100//初始分配量
#define LISTINCREMENT 10//分配增量
#define OK 1
#define Fail 0
#define False 0
#define True 1
typedef定义数据类型和结构体
typedef int ElemType;
typedef int Status;
typedef struct{
ElemType* elem;
int length;//长度
int listsize;//存储容量 //长度<=存储容量
}Sqlist;
InitList(创建)
Status InitList_Sq(Sqlist* L){//创建
//地址方式调用 ,获得传入参数(地址)对应的对象
L->elem=(ElemType*)malloc(LIST_INIT_SIZE* sizeof(ElemType));//分配内存空间 ,malloc的返回值是一个指针,指向一段可用内存的起始地址
if(!L->elem)exit(OVERFLOW);
L->length=0;
L->listsize=LIST_INIT_SIZE;
return OK;
}
DestroyList(销毁)
Status DestroyList_Sq(Sqlist* L){//销毁
L->length=0;
L->listsize=0;
free(L->elem);
return OK;
}
ClearList(清空)
Status ClearList_Sq(Sqlist* L){//清空
L->length=0;
return OK;
}
ListEmpty(判断表是否为空)
Status ListEmpty_Sq(Sqlist L){//判断顺序表是否为空
if(L.length==0)
return True;
else
return False;
}
ListLength(获得数据元素的个数)
Status ListLength_Sq(Sqlist L){//返回数据元素个数
return L.length;
}
GetElem(获得第某个数据元素)
Status GetElem_Sq(Sqlist L,int i,ElemType* e){//返回第i个元素的值,将其存储在e中
if (i>=1&&i<=L.length){
* e=L.elem[i-1];
return OK;
}
}
Locate( 匹配数据元素)
需要先实现compare()方法。
Status compare(int i,int j){//在Locate_Sq()方法中用到
if(i==j)
return 1;
else
return 0;
}
Status Locate_Sq(Sqlist L,ElemType e,int compare()){//返回顺序表中与参数e相等的数据元素的次序
int i=0;
int flag=0;
for(i=0;i<L.length;i++){
flag=compare(L.elem[i],e);//调用compare函数依次比较参数e和L中的数据元素 ,结果保存在flag中
if(flag==1){
return i+1;//若找到相同的(flag=1),返回该数据元素的次序 (L.elem[i]中的i从0开始,因此加1)
}
}
return Fail;
}
PriorElem(获得前驱数据元素)
Status PriorElem_Sq(Sqlist L,ElemType cur_e,ElemType* pre_e){//找前驱,并将pre_e修改为前驱,需要用到compare函数
int i=0;
i=Locate_Sq(L,cur_e,compare);
if(i>1){//若cur_e是表中元素(不是0),且不是第一个 (1)
*pre_e=L.elem[i-2];//i是cur_e的次序,前驱的次序应-1,前驱的L.elem[j]应再-1
}
}
NextElem(获得后继数据元素)
Status NextElem_Sq(Sqlist L,ElemType cur_e,ElemType* next_e){//找后继,并将pre_e修改为前驱,需要用到compare函数
int i=0;
i=Locate_Sq(L,cur_e,compare);
if(i>0&&i<L.length){//若cur_e是表中元素(不是0),且不是最后一个 (L.length)
*next_e=L.elem[i];//i是cur_e的次序,后继的次序就是L.elem[i]
}
}
ListInsert(插入数据元素)
Status ListInsert_Sq(Sqlist* L,int i,ElemType e){//在第i个位置之前插入新的数据元素e
if(i>=1&&i<=L->listsize){
L->length++;
int j=L->length;
for(j;j>i;j--){
L->elem[j-1]=L->elem[j-2];
}
L->elem[i]=e;
}
return OK;
}
ListDelete(删除数据元素)
Status ListDelete_Sq(Sqlist* L,int i,ElemType* e){//删除第i个位置的元素,将其值保存在e中
if(i>=1&&i<=L->listsize){
*e=L->elem[i-1];//第i个位置的元素对应的是elem[i-1],改变e的值使其等于elem[i-1]
for(i;i<L->length;i++){
L->elem[i-1]=L->elem[i];
}
}
L->length--;
return OK;
}
ListTraverse(遍历所有数据元素)
需要先实现visit()函数。
Status visit(Sqlist L){//访问元素,在ListTraverse()中用到
int i=0;
for(i;i<L.length;i++){
printf("%d\n",L.elem[i]);
}
return i;//返回遍历的元素个数
}
Status ListTraverse(Sqlist L,int visit()){
if(visit(L)==L.length){
return OK;
}
}
输入样例
很多函数被我注释掉了,需要使用的话自行取消注释。
int main(void){
Sqlist L;
InitList_Sq(&L);//创建表,传入表对应的地址
L.elem[0]=1;//第一个元素
L.elem[1]=3;//第二个元素
L.elem[2]=5;//第三个元素
L.elem[3]=7;//第四个元素
L.length=4;//共四个元素
//int elem1=0;
//GetElem_Sq(L,2,&elem1);//获得第二个元素的值(3),存储在elem1中
//Locate_Sq(L,5,compare);//在顺序表中查找值为5的数据元素,若找到则返回次序
//PriorElem_Sq(L,L.elem[2],&elem1);//将elem[2]的前驱存储在elem1中
//NextElem_Sq(L,L.elem[2],&elem1);//将elem[2]的后继存储在elem1中
//ListInsert_Sq(&L,2,-1); //将值为-1的数据元素插入到第二个元素后面
//ListDelete_Sq(&L,2,&elem1); //删除第二个元素(L.elem[1])
ListTraverse(L,visit);//遍历所有元素并输出,成功则返回OK
DestroyList_Sq(&L);//销毁表
}