刚开始学数据结构,几乎算是什么都不会,想记录一下学习的东西,所以就学别人开始写博客。
刚学了顺序存储的线性表的基本操作,把操作写了一遍。可能会有错误。
顺序存储的线性表,用结构体类型。注意:结构体并不是用来存储元素的,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} (或许只要一句话就会这样)