/*
线性结构的基本特征:
1. 集合中必存在唯一的一个“第一元素”
2. 集合中必存在唯一的一个“最后元素”
3. 除最后元素之外,均有唯一的后继
4. 除第一元素之外,均有唯一的前驱
对线性表的基本操作:
{结构初始化}
InitList(&L); //构造一个空的线性表L
{结构的销毁}
DestroyList(&L); //销毁线性表L
{引用型操作}
ListEmpty(L); //线性表判空
ListLength(L); //返回线性表长度
PriorElem(L, cur_e, &pre_e); //返回当前元素前驱
NextElem(L, cur_e, &next_e); //返回当前元素后继
GetElem(L, i, &e); //返回第i个元素的值
Locate(L, e.compare()); //返回 L中第1个与e满足关系compare()的元素的位序,若不存在,返回0
ListTraverse(L, visit()); //遍历线性表
{加工型操作}
ClearList(&L); //将L重置为空表
ListInsert(&L, i, e); //在第i个元素之前插入新的元素e,L的长度加1
ListDelete(&L, i, &e); //删除L的第i个元素,并用e返回,L的长度减1
*/
#include<stdio.h>
#include<stdlib.h>
//定义数据类型
typedef int ElemType;
//顺序表的存储结构
#define LIST_INIT_SIZE 10 //线性表存储空间的初始分配量
#define LISTINCREMENT 7 //线性表存储空间的分配增量
typedef struct {
ElemType *elem; //存储空间基址
int length; //线性表当前长度
int listsize; //线性表当前的存储容量(以sizeof(ElemType)为单位)
}SqList;
//声明,指针函数
bool (*compare)(ElemType e1, ElemType e2);
void (*visit)(ElemType e);
//声明,辅助函数
bool equals(ElemType e1, ElemType e2);
void visitElem(ElemType e);
//声明,对线性表的基本操作
//将有返回值的方法写成ElemType f(),即return (ElemType)i,可能效果更好一些
bool InitList(SqList &L); //初始化一个空表
bool DestroyList(SqList &L); //销毁线性表
bool ListEmpty(SqList L); //线性表判空
int ListLength(SqList L); //线性表长度
void PriorElem(SqList L, ElemType cur_e, ElemType &pre_e); //返回当前元素的前驱
void NextElem(SqList L, ElemType cur_e, ElemType &next_e); //返回当前元素的后继
void getElem(SqList L, int i, ElemType &e); //返回第i个元素的值,0表示第一个元素
void getTail(SqList L, ElemType &e); //返回第最后一个元素
void getHead(SqList L, ElemType &e); //返回第一个元素
int LocateElem(SqList L, ElemType e, bool (*compare)(ElemType e1, ElemType e2));
//返回线性表中与e满足compare关系的第一个元素的位置
void ListTraverse(SqList L, void (*visit)(ElemType e)); //遍历线性表
void ClearList(SqList &L); //将线性表置空
void ListInsert(SqList &L, int i, ElemType e); //在第i个元素之前插入
void AppendTail(SqList &L, ElemType e); //在表尾插入,即插入为最后一个元素
void AppendHead(SqList &L, ElemType e); //在表头插入,即插入为第一个元素
void ListDelete(SqList &L, int i, ElemType &e); //删除第i个元素,并用返回删除的元素
void DeleteTail(SqList &L, ElemType &e); //删除表尾元素,即删除最后一个元素
void DeleteHead(SqList &L, ElemType &e); //删除表头元素,即删除第一个元素
//测试模块
int main(){
SqList L;
InitList(L);
//给线性表中插入元素,遍历
for (int i = 1; i < 18; i++){
if (i % 3 == 0)
AppendTail(L, i);
else if (i % 4 == 0)
ListInsert(L, 3, i);
else
AppendHead(L, i);
}
ListTraverse(L, visitElem);
printf("\n\n");
//求第一个元素前驱(返回错误),除第一个元素外其他元素的前驱,线性表中不存在的元素的前驱(
//返回错误)
ElemType e;
ElemType e1;
PriorElem(L, 12, e);
printf("12的前驱是:%d\n\n", e);
getHead(L, e1);
PriorElem(L, e1, e);
printf("%d的前驱是:%d\n\n", e1, e);
PriorElem(L, 21, e);
printf("21的前驱是:%d\n\n", e);
//求最后一个元素后继(返回错误),除最后一个元素外其他元素后继,线性表中不存在的元素的后继(
//返回错误)
NextElem(L, 12, e);
printf("12的后继是:%d\n\n", e);
getTail(L, e1);
NextElem(L, e1, e);
printf("%d的后继是:%d\n\n", e1, e);
NextElem(L, 21, e);
printf("21的后继是:%d\n\n", e);
//删除第一个元素,删除最后一个元素,删除其他元素,删除超出线性表长度的元素(返回错误)
DeleteHead(L, e);
printf("删除的元素是:%d\n\n", e);
DeleteTail(L, e);
printf("删除的元素是:%d\n\n", e);
ListDelete(L, 3, e);
printf("删除的元素是:%d\n\n", e);
ListDelete(L, 21, e);
printf("删除的元素是:%d\n\n", e);
ListTraverse(L, visitElem);
printf("\n\n");
system("pause");
return 0;
}
//各函数定义模块
bool equals(ElemType e1, ElemType e2){
if (e1 == e2)
return true;
else return false;
}
void visitElem(ElemType e){
printf("%4d", e);
}
bool InitList(SqList &L){ //初始化一个空表
L.elem = (ElemType*)malloc(sizeof(ElemType)*LIST_INIT_SIZE);
if (!L.elem)
return false;
L.length = 0;
L.listsize = LIST_INIT_SIZE;
return true;
}
bool DestroyList(SqList &L){ //销毁线性表
if (L.elem){
free(L.elem);
return true;
}
return false;
}
bool ListEmpty(SqList L){ //线性表判空
if (L.length == 0)
return true;
else return false;
}
int ListLength(SqList L){ //线性表长度
return L.length;
}
void PriorElem(SqList L, ElemType cur_e, ElemType &pre_e){ //返回当前元素的前驱
int curPos = LocateElem(L, cur_e, equals);
if (curPos > 0){
pre_e = L.elem[curPos - 1];
}
else{
if (curPos == 0){
printf("当前元素是线性表中第一个元素,没有后继\n");
pre_e = -1;
}
else{
printf("线性表中不存在该元素!\n");
pre_e = -1;
}
}
}
void NextElem(SqList L, ElemType cur_e, ElemType &next_e){ //返回当前元素的后继
int curPos = LocateElem(L, cur_e, equals);
if (curPos > -1 && curPos < L.length - 1){
next_e = L.elem[curPos + 1];
}
else{
if (curPos == L.length - 1){
printf("当前元素是线性表中最后一个元素,没有前驱\n");
next_e = -1;
}
else{
printf("线性表中不存在该元素!\n");
next_e = -1;
}
}
}
void getElem(SqList L, int i, ElemType &e){ //返回第i个元素的值,0表示第一个元素
if (i<1 || i>L.length){
printf("当前索引超出线性表的范围!\n");
return;
}
e = L.elem[i - 1];
}
void getTail(SqList L, ElemType &e){ //返回第最后一个元素
getElem(L, L.length, e);
}
void getHead(SqList L, ElemType &e){ //返回第一个元素
getElem(L, 1, e);
}
int LocateElem(SqList L, ElemType e, bool(*compare)(ElemType e1, ElemType e2)){
//返回线性表中与e满足compare关系的第一个元素的位置
for (int i = 0; i < L.length; i++){
if (compare(e, L.elem[i]))
return i;
}
return -1;
}
void ListTraverse(SqList L, void(*visit)(ElemType e)){ //遍历线性表
for (int i = 0; i < L.length; i++){
if (i % 4 == 0)
printf("\n");
visit(L.elem[i]);
}
}
void ClearList(SqList &L){ //将线性表置空
L.length = 0;
}
void ListInsert(SqList &L, int i, ElemType e){ //在第i个元素之前插入
//判断插入的位置是否合法
if (i<1 || i>L.length + 1){
printf("插入的位置不合法!\n");
return;
}
//判断链表的存储空间是否足够
if (L.length >= L.listsize){
ElemType *newElem = (ElemType*)realloc(L.elem, (L.listsize + LISTINCREMENT)*sizeof(ElemType));
if (!newElem)
return;
L.elem = newElem;
L.listsize += LISTINCREMENT;
}
ElemType *iPos = &L.elem[i - 1];
ElemType *tailPos = L.elem + L.length - 1;
for (; tailPos >= iPos; tailPos--)
*(tailPos + 1) = *tailPos;
*iPos = e;
L.length++;
}
void AppendTail(SqList &L, ElemType e){ //在表尾插入,即插入为最后一个元素
ListInsert(L, L.length + 1, e);
}
void AppendHead(SqList &L, ElemType e){ //在表头插入,即插入为第一个元素
ListInsert(L, 1, e);
}
void ListDelete(SqList &L, int i, ElemType &e){ //删除第i个元素,并用返回删除的元素
//判断删除的位置是否合法
if (i<1 || i>L.length){
printf("删除的位置不合法!\n");
e = -1;
return;
}
ElemType *iPos = &L.elem[i - 1];
ElemType *tailPos = L.elem + L.length - 1;
e = *iPos;
for (; iPos <= tailPos; iPos++)
*iPos = *(iPos + 1);
L.length--;
}
void DeleteTail(SqList &L, ElemType &e){ //删除表尾元素,即删除最后一个元素
ListDelete(L, L.length, e);
}
void DeleteHead(SqList &L, ElemType &e){ //删除表头元素,即删除第一个元素
ListDelete(L, 1, e);
}