刚开始学数据结构,几乎算是什么都不会,想记录一下学习的东西,所以就学别人开始写博客。
刚学了顺序存储的线性表的基本操作,把操作写了一遍。可能会有错误。
顺序存储的线性表,用结构体类型。注意:结构体并不是用来存储元素的,elem才是存储元素的首地址
1 typedef struct
2 {
3 ElemType *elem;//存储空间基地址
6 int length;//表长
7 int listsize;//表容量
8 }SqList;
初始化:构造空表L,返回一个状态,需要带回一个表给基地址动态分配一定大小的空间,表长赋0,表容量赋值
注意:开辟内存失败;
1 Status InitList_Sq(SqList &L)//L为结构体的一个变量,所以在使用它的成员时用L.
2 {
3 L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
4 if(!L.elem)
5 exit(OVERFLOW);
6 L.length=0;
7 L.listsize=LIST_INIT_SIZE;
8 return OK;
9 }
创建表:先初始化,再依次输入每个元素,返回状态,传一个表、输入几个数,带回一个表
注意:每输入一个表长+1 这里的输入不通用,只能输入整型数据。也可以用初始化和插入函数实现
1 Status CreaList_Sq(SqList &L,int n)
2 {
3 L.elem=(ElemType *)malloc(LIST_INIT_SIZE*sizeof(ElemType));
4 if(!L.elem)
5 exit(OVERFLOW);
6 L.length=0;
7 L.listsize=LIST_INIT_SIZE;//初始化
8
9 ElemType *p;
10 p=L.elem;//为了练习指针,所以多用
11 while(p<=L.elem+n-1)
12 {
13 scanf("%d",p);//p本身就是地址,与&*p含义相同;
14 L.length++;
15 p++;//别忘了
16 }
17 return OK;
18
19 }
销毁表:返回状态,传一个表,带回把空间释放,表长和表容量赋0
注意:释放空间
1 Status DestroyList_Sq(SqList &L)
2 {
3 free(L.elem);
4 L.elem=NULL;
5 L.length=0;
6 L.listsize=0;
7 return OK;
8 }
清空表:把表长赋0,返回状态,带回表区别于销毁表
注意:
1 Status ClearList_Sq(SqList &L)
2 {
3 L.length=0;
4 return 0;
5 }
判空谓词:返回状态,传入一个表,看表长
注意:
1 Status IsListEmpty(SqList L)
2 {
3 return L.length==0? TRUE:FALSE;
4 } (为什么不自动分行了)
表长:返回表中数据元素个数 传一个表
注意:
int ListLength(SqList L)
{
return L.length;
}
获取第i个元素:返回状态,传一个表,位置,存第i个元素的变量,带回该变量
注意:i的位置不合法
1 Status GetElem_Sq(SqList L,int i,ElemType &e)
2 {
3 if(i<1||i>L.length)
4 return ERROR;//正常人都从1开始数数
5
6 e=*(L.elem+i-1);
7
8 return OK;
9
10 }
查找:查找符合条件的第一个元素,返回它的位序传一个表,要查的元素,一个函数指针
注意:
1 int LocateElem_Sq(SqList L,ElemType e,Status(*compare)(ElemType,ElemType))
2 {
3 ElemType *p=L.elem;
4 int i=1;//记录位置
5 while(p<=L.elem+L.length-1&&compare(*p,e)==FALSE)//或写成(*compare)(*p,e);
6 {
7 p++;
8 i++;
9 }
10 if(p<=L.elem+L.length-1)
11 return i;
12
13 return ERROR;
14 }
写一个函数指针对应的比较谓词吧
1 Status IsEqual(ElemType a,ElemType e)
2 {
3 return a==e? TRUE:FALSE;
4 }
元素的前驱:找到第一个该元素,如果不是第一个,就带回它的前驱返回状态,传一个表,一个元素,一个带回元素的变量
注意:第一个元素
Status PriorElem_Sq(SqList L,ElemType cur_e,ElemType &pre_e)
{
int i=1;
ElemType *p=L.elem;
while(i<=L.length&&*p!=cur_e)
{
p++;
i++;
}
if(i!=1&&i<=L.length)
{
pre_e=*(L.elem+i-2);
return OK;
}
return ERROR;
}
元素的后继:带回一个元素的后一个返回一个状态,传一个表,一个该元素,一个带回元素的变量
注意:最后一个元素
Status NextElem_Sq(SqList L,ElemType cur_e,ElemType &nex_e)
{
ElemType *p=L.elem;
int i=1;
while(i<=L.length&&*p!=cur_e)
{
p++;
i++;
}
if(i<L.length)
{
nex_e=*(L.elem+i);//注意带回的是谁
}
return ERROR;
}
插入:在第i个元素前插入一个元素返回状态,传入一个表,位置i,元素,带回一个表
注意:i的位置不合法,表长+1,表满扩容
Status ListInsert_Sq(SqList &L,int i,ElemType e)
{
if(i<=0||i>L.length+1)
return ERROR;
if(L.length>=L.listsize)
{
L.elem=(ElemType *)realloc(L.elem,(LIST_INIT_SIZE+LISTINCREMENT)*sizeof(ElemType));
if(!L.elem)
exit(OVERFLOW);
L.listsize+=LISTINCREMENT;
}//扩容
for(int j=L.length;j>=i;--j)
*(L.elem+j)=*(L.elem+j-1);//第i个元素后移
*(L.elem+i-1)=e;
L.length++;
return OK;
}
删除:输出第i个元素,并带回它返回状态,传一个表,位置i,一个带回元素的变量,带回表
注意:i的位置,表长-1,带回元素
1 Status ListDelete_Sq(SqList &L,int i,ElemType &e)
2 {
3 if(i<1||i>L.length)
4 return ERROR;
5
6 e=*(L.elem+i-1);
7
8 for(int j=i;j<L.length;++j)//注意结束位置是到数第二个
9 {
10 *(L.elem+j-1)=*(L.elem+j);
11 }
12
13 --L.length;
14
15 return OK;
16 }
遍历:依次对表中的元素执行一个传入的操作,如果执行失败就返回错误返回状态,传一个表和函数指针
注意:空表
1 Status ListTraverse(SqList L,Status (*vist)(ElemType))
2 {
3 if(!L.length)
4 return ERROR;
5
6 ElemType *p=L.elem;
7 while(p<=L.elem+L.length-1)
8 {
9 if(!vist(*p))//或者(*vist)(*p);
10 return ERROR;
11 p++;
12 }
13
14 return OK;
15
16 }
写一个与函数指针对应的
1 Status Print_e(ElemType e)
2 {
3 printf("%d ",e);
4} (或许只要一句话就会这样)
来源:oschina
链接:https://my.oschina.net/u/4289606/blog/3397412