线性表作为数据结构开篇内容对一些算法设计思想和C语言的基本语法要求还是比较高的,再加上老师上课以2倍速的方式讲课,弄的小编天天被这门课程折磨着。但是作为一个程序员,没有经历过深夜敲代码找bug,总会感觉自己的编程之路缺了点什么。看似简单的数学问题,但是要用计算机是思维去实现还是一个需要不断锻炼与提高的过程。本篇博客是基于《数据结构 C语言版 清华大学出版社》完成的,上面的一些变量名称命名与课本基本保持一致,可以方便以后的复习。上面的一些复杂定义类型不太适合初学者,但是自己慢慢分析也是能够理顺的。
(希望自己以后能够坚持下来写自己的技术博客 耶!)
#include <iostream>
#include <cstdlib>
using namespace std;
typedef int ElemType;
typedef int Status; //定义ElemType类型为int
# define LIST_INIT_SIZE 100 // 线性表存储空间的初始分配量
# define LISTINCREMENT 10 // 线性表存储空间的分配增量
#define OK 1
#define ERROR -1
#define OVERFLOW -2
//引导提示
void show_help()
{
cout<<"1----清空线性表"<<endl;
cout<<"2----判断线性表是否为空"<<endl;
cout<<"3----求线性表长度"<<endl;
cout<<"4----获取线性表指定位置元素"<<endl;
cout<<"5----求前驱"<<endl;
cout<<"6----求后继"<<endl;
cout<<"7----在线性表指定位置插入元素"<<endl;
cout<<"8----删除线性表指定位置元素"<<endl;
cout<<"9----显示线性表"<<endl;
cout<<" 退出,输出一个负数!"<<endl;
}
//生成一个线性表SqList
typedef struct { //若后面不再用,可省略结构名
ElemType *elem; //存储空间基址
int length; //当前表长(特指元素个数)
int listsize; //当前分配的存储容量(以sizeof(ElemType)为单位)
}SqList;
//定义初始化一个空的线性表L
Status InitList_Sq(SqList &L)
{
L.elem = new ElemType[LIST_INIT_SIZE]; //动态分配线性表的内存单元
L.length = 0; // 空表长度为0
L.listsize = LIST_INIT_SIZE; // 初始存储容量
return OK;
}
//1.销毁线性表
void DestroyList(SqList &L)
{
if (L.elem) delete[ ] L.elem; //释放存储空间
L.length=0;
L.listsize=0;
}
//2.判断线性表是否为空
bool IsEmpty(SqList L)
{
if (L.length==0)
return true;
else
return false;
}
//3.获取线性表的长度
int GetLength(SqList L)
{
return L.length;
}
//4.获取线性表指定位置元素
Status GetElem(SqList &L,int i)
{
if(i<1||i>L.length+1)
return ERROR;
else
cout<<L.elem[i-1]<<endl;
}
//5.求前驱
Status GetPre(SqList &L,int i)
{
if(i<2||i>L.length+1)
return ERROR;
else
cout<<L.elem[i-2]<<endl;
}
//6.求后继
Status GetNex(SqList &L,int i)
{
if(i<1||i>L.length-1)
return ERROR;
else
cout<<L.elem[i]<<endl;
}
//7.在线性表中插入某元素
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
if(i<1 || i>L.length+1)
return ERROR; //i值不合法
if (L.length== LIST_INIT_SIZE )//当前存储空间已满,增加分配
{
//newbase为一个指针需要定义
ElemType *newbase=(ElemType*)realloc(L.elem,(L.listsize+LISTINCREMENT)*sizeof(ElemType));
if (!newbase)
exit(OVERFLOW); //存储分配失败
L.elem=newbase; //新基址
L.listsize+=LISTINCREMENT; //增加存储容量
}
ElemType *q=&(L.elem[i-1]); //q为插入位置
for (ElemType *p=&L.elem[L.length-1]; p>=q; --p)
*(p+1)=*p; //插入位置之后的元素右移
*q=e; //插入e
++L.length; //表长增1
return OK;
}
//8.在顺序表L中删除第i个元素,并用e返回其值
Status ListDelete_Sq(SqList &L,int i,ElemType &e)
{
if(i<1||i>L.length)
return ERROR;
int *p;
int *q;
p=&(L.elem[i-1]);//p为被删除元素的位置
e=*p;
q=L.elem+L.length-1;
for(++p;p<=q;++p)
*(p-1)=*p;
--L.length;
return OK;
}
//9.输出线性表
void Display_List(SqList L)
{
for(int i=1;i<=L.length;++i)
cout<<L.elem[i-1]<<" ";
cout<<endl;
}
int main()
{
int operate_code;
show_help();
SqList L;//定义线性表变量,如SqList L;
InitList_Sq(L); //调用初始化线性表函数
while(1)
{
cout<<"请输入操作代码:";
cin>>operate_code;
if(operate_code==1)
{
DestroyList(L);
}
else if(operate_code==2)
{
if(IsEmpty(L))
cout<<"The list is empty"<<endl;
else
cout<<"The list is not empty"<<endl;
}
else if(operate_code==3)
{
cout<<"The length of list is:"<<GetLength(L)<<endl;
}
else if(operate_code==4)
{
int i;
cout<<"请输入线性表元素的位置,获取该位置的元素:"<<endl;
cin>>i;
GetElem(L,i);
}
else if(operate_code==5)
{
int i;
cout<<"请输入线性表元素的位置,获取该位置元素的前驱元素:"<<endl;
cin>>i;
GetPre(L,i);
}
else if(operate_code==6)
{
int i;
cout<<"请输入线性表元素的位置,获取该位置元素的后继元素:"<<endl;
cin>>i;
GetNex(L,i);
}
else if(operate_code==7)
{
int e,i;
cout<<"请输入要插入元素及其位置:"<<endl;
cin>>e>>i;
ListInsert_Sq(L,i,e);
// cout<<"e="<<e<<" i="<<i<<endl;
}
else if(operate_code==8)
{
int e,i;
cout<<"请输入要删除元素的位置:"<<endl;
cin>>i;
ListDelete_Sq(L,i,e);
}
else if(operate_code==9)
{
cout<<"The elements of the list are:"<<endl;
Display_List(L);
}
else if(operate_code<0)
{
break;
}
else
{
cout<<"\n操作码错误!!!"<<endl;
show_help();
}
}
DestroyList(L);
return 0;
}