上传源码,学习交流,有什么需要改进的地方还希望各位给予指点。
参考书目:《数据结构(C语言版)》,严蔚敏
common.h
#ifndef _COMMON_H_
#define _COMMON_H_
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
#define OVERFLOW -2
typedef int Status;
Status Equal(int a, int b);
#endif
common.c
#include "Common.h"
Status Equal(int a, int b)
{
if(a==b) return TRUE;
else return FALSE;
}
SqList.h
#ifndef _SQLIST_H_
#define _SQLIST_H_
#include <stdlib.h>
#include "Common.h"
#define ElemType int
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量
#define LISTINCREMENT 10 //线性表存储空间的分配增量
typedef struct SqList_
{
ElemType *elem; //存储空间基址
int length; //当前长度
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
} SqList;
//基本操作
Status InitList_Sq(SqList *L);
//操作结果:构造一个空的线性表L
Status ListInsert_Sq(SqList *L,int i,ElemType e);
//初始条件:线性表L已存在,1 <= i <= ListLength(&L) + 1
//操作结果:在线性表L的第i个位置之前插入新元素e,L长度加1
Status ListScanf_Sq(SqList *L);
//初始条件:线性表L已存在
//操作结果:向L中输入数据
Status ListDisp_Sq0(SqList *L); //实际应用时不使用这个函数
//初始条件:线性表L已存在
//操作结果:显示L中的元素,遇到0时终止,并且不显示0。(显然不可靠)
Status ListDisp_Sq(SqList *L);
//初始条件:线性表L已存在
//操作结果:显示当前L中所有的元素
Status ListDelete_Sq(SqList *L,int i,ElemType *e);
//初始条件:线性表L已存在且非空,1 <= i <= ListLength(&L)
//删除L的第i个数据元素,并用e返回其值,L的长度减1
int LocateElem_Sq(SqList *L,ElemType e,Status (*compare)(ElemType ,ElemType ));
#endif
SqList.c
#include <stdio.h>
#include <stdlib.h>
#include "SqList.h"
/*
输入参数:*L 待初始化的线性表头结点
返回参数:OVERFLOW 存储空间不够用
OK 初始化成功
函数功能:对顺序线性表头结点进行初始化
*/
Status InitList_Sq(SqList *L)
{
L->elem = (ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
if(!L->elem)
exit(OVERFLOW); //存储分配失败
L->length = 0; //空表长度为0
L->listsize = LIST_INIT_SIZE; //初始存储容量
return OK;
}
/*
输入参数:*L 待处理的线性表头结点
返回参数:线性表的当前长度
函数功能:返回线性表的当前长度
*/
int ListLength_Sq(SqList *L)
{
return(L->length);
}
/*
输入参数:*L 待输入线性表的头结点
返回参数:ERROR 失败
OK 成功
函数功能:向指定的线性表输入数据,每输入完一个数据按一下回车(或者空格键),约定当输入0时自动终止输入,并将0存入线性表。
说明:若想向线性表中输入0,则可以通过函数ListInsert_Sq()来实现。
*/
Status ListScanf_Sq(SqList *L)
{
SqList *p;
p=L;
if(p == NULL)
{
return ERROR; //该链表不存在
}
scanf("%d",(p->elem + p->length));
while(p->elem[p->length] != 0)
{
p->length++;
if(p->length >= L->listsize)
{
printf("The linear list is full.");
break;
}
scanf("%d",(p->elem + p->length));
}
return OK;
}
/*
输入参数:*L 待显示线性表的头结点
返回参数:ERROR 失败
OK 成功
函数功能:显示线性表,遇到0时终止,并且不显示0
*/
Status ListDisp_Sq0(SqList *L)
{
unsigned int i=0;
SqList *p=L;
if(p == NULL)
{
return ERROR; //该链表不存在
}
printf("\n\n\n************** output start **************\n");
while(p->elem[i] != 0) //这个判断只能显示非0的元素,且一旦遇到0就会停止显示,这只针对我定义的ListScanf()函数。而且当线性表中的所有数据都不为0时,该判断还会显示线性表之外的数据。然而我们可以按照线性表长度来显示线性表中所有的元素。
{
printf("%d ",p->elem[i++]);
}
printf("\n************** output end **************\n");
return OK;
}
/*
输入参数:*L 待显示线性表的头结点
返回参数:ERROR 失败
OK 成功
函数功能:按顺序线性表的长度显示线性表,即显示当前线性表中所有的元素
*/
Status ListDisp_Sq(SqList *L)
{
int i=0,len;
SqList *p=L;
if(p == NULL)
{
return ERROR; //该链表不存在
}
len = ListLength_Sq(L);
printf("\n\n\n************** output start **************\n");
while(i < len)
{
printf("%d ",p->elem[i++]);
}
printf("\n************** output end **************\n");
return OK;
}
/*
输入参数:*L 待插入线性表的头结点
i 待插入位置(1 <= i <= ListLength(&L) + 1)
e 待插入数据
返回参数:ERROR 操作失败
OK 操作成功
函数功能:在顺序线性表L的第i个位置之前插入新元素e,L长度加1
*/
Status ListInsert_Sq(SqList *L,int i,ElemType e)
{
ElemType *newnode,*p,*q;
if(i < 1 || i > L->length + 1) return ERROR; //i值不合法
if(L->length >= L->listsize)
{
newnode = (ElemType *)realloc(L->elem, (L->listsize + LISTINCREMENT)*sizeof(ElemType));
if(!newnode) exit(OVERFLOW);
L->elem = newnode; //新的首地址不一定与原地址相同,因为为了增加空间,存储区会进行必要的移动。
L->listsize += LISTINCREMENT;
}
q = L->elem + i - 1;
for(p = L->elem + L->length - 1; p >= q; p--)
{*(p+1) = *p;} //插入位置及之后的元素右移
*q = e;
L->length++;
return OK;
}
/*
输入参数:*L 待删除结点的链表头结点
i 待删除结点的位置
e 待删除结点的值
返回参数:ERROR 操作成功
OK 失败
函数功能:删除顺序线性表L中的第i个元素,并用e返回其值。
*/
Status ListDelete_Sq(SqList *L,int i,ElemType *e)
{
ElemType *p,*q;
if((i<1) || (i>L->length)) return ERROR;
p = L->elem + i - 1;
*e = *p;
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//这段程序的操作效率相对不高。
// while(i <= L->length)
// {
// p++;
// *(p-1) = *(p);
// i++;
// }
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
//>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
//下面这段程序相对上面的较高。
q = L->elem + L->length - 1;
for(p++; p <= q; p++)
{*(p-1) = *p;}
//<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
L->length--;
return OK;
}
/*
输入参数:*L 待查找链表的头结点
e 待比较元素
compare 数据元素比较函数,或者叫判定函数
返回参数:i 顺序线性表中第1个与e满足关系compare()的元素的位置
函数功能:返回L中第一个与e满足关系compare()的元素的位序,若这样的数据元素不存在,则返回值为0。
*/
int LocateElem_Sq(SqList *L,ElemType e,Status (*compare)(ElemType ,ElemType ))
{
int i=0;
ElemType *p;
p=L->elem;
while(i++ <= L->length && !(*compare)(*p++,e))
{
//i++;
//p++;
}
if(i <= L->length) return i;
else return FALSE;
}
main.c
int main()
{
ElemType dat;
SqList L;
InitList_Sq(&L);
ListScanf_Sq(&L);
ListDisp_Sq(&L);
printf("@@@@@@@@@@@@@@@@@@@@@\n");
ListInsert_Sq(&L,4,1010);
ListDisp_Sq(&L);
printf("@@@@@@@@@@@@@@@@@@@@@\n");
ListDelete_Sq(&L,9,&dat);
ListDisp_Sq(&L);
printf("dat=%d\n",dat);
printf("%d\n",LocateElem_Sq(&L,3,Equal));
}
运行输出结果如下: