顺序表学习:参考《大话数据结构》
涉及到顺序表的基本操作有如下:
int initList(SqList *L); /** 初始化操作,建立一个空的线性表 **/
int printList(SqList L); /** 打印线性表中的每一个元素 **/
int getlength(SqList L); /** 返回线性表元素的个数 **/
int createList(SqList *L,int length); /** 创建一个链表长度为length的线性表 **/
int insertList(SqList *L, int pos,ElemType elem); /** 在线性表的第pos个位置插入 一个新元素elem **/
int getElem(SqList L, int pos, ElemType *e); /** 将线性表中第pos个位置的元素返回,保存在*e中 **/
int locateElem(SqList L, ElemType e); /** 在线性表中查找与给定元素e相等的元素,如果有相同的返回状态值1,如果没有,返回状态值0 **/
int deleteList(SqList *L, int pos,ElemType *elem); /** 从线性表中删除pos位置处的元素,并将其存放在elem中; **/
int clearList(SqList L,SqList *pL); /** 清空顺序表 **/
(一)ADT
1 typedef int ElemType; 2 typedef struct{ // 线性表中共有length个元素,是data[0]——data[length-1] 3 int data[MAXSIZE]; 4 int length; 5 }SqList;
(二)初始化一个顺序表
1 int initList(SqList *L) 2 { 3 L->length=0; 4 return 1; 5 }
(三)打印一个顺序表,方便测试操作结果是否正确
1 int printList(SqList L) 2 { 3 if(L.length==0) 4 { printf("链表为空\n"); 5 return 0; 6 } 7 int i; 8 for(i=0;i<L.length;i++){ 9 printf("data[%d] = %d\n",i,L.data[i]); 10 } 11 printf("\n"); 12 return 1; 13 }
(四)获取顺序表的长度
1 int getlength(SqList L){ 2 return L.length; 3 }
(五)创建一个顺序表,每个元素的值随机赋值
1 int createList(SqList *L,int length){ 2 srand(time(0)); 3 int i; 4 for(i=0;i<length;i++){ 5 L->data[i]=rand()%100; 6 L->length++; 7 } 8 return 1; 9 }
(六)在指定位置处插入一个新的元素
1 int insertList(SqList *L, int pos,ElemType elem){ 2 int i; 3 if(pos<1 || pos>L->length) 4 { 5 printf("插入的位置有误,无法插入数据\n"); 6 return 0; 7 } 8 for (i=L->length-1;i>=pos-1;i--) 9 { 10 L->data[i+1]=L->data[i]; 11 } 12 L->data[pos-1] = elem; 13 L->length++; 14 return 1; 15 }
(七)获取顺序表中指定位置处的元素值
1 int getElem(SqList L, int pos, ElemType *e){ 2 if(pos<1 || pos>L.length) 3 { 4 printf("查找位置有错误,无法获取指定位置的数据\n"); 5 *e=99999999; 6 return 0; 7 } 8 *e = L.data[pos-1]; 9 return 1; 10 }
(八)查找在线性表中是否含有指定元素
1 int locateElem(SqList L, ElemType e){ 2 int i; 3 for(i=0;i<L.length;i++) 4 { 5 //printf("在%d层循环...\n",i); 6 if(L.data[i] == e) 7 { 8 printf("在pos[%d]位置处,查找到了元素elem:%d\n",i+1,e); 9 return 1; 10 } 11 } 12 return 0; 13 }
(九)删除顺序表中指定位置处的元素
1 int deleteList(SqList *L, int pos,ElemType *elem){ 2 int i; 3 if(pos<1 || pos>L->length) 4 { 5 printf("删除的位置有误,无法从该位置删除数据\n"); 6 *elem=99999999; 7 return 0; 8 } 9 *elem = L->data[pos-1]; 10 for(i=pos;i<L->length;i++){ 11 L->data[i-1]=L->data[i]; 12 } 13 L->length --; 14 return 1; 15 }
(十)清空一个顺序表,将顺序表的length置为0;
1 int clearList(SqList L,SqList *pL){ 2 printf("In clearList function: %d\n",&L); 3 printf("In clearList function: %d\n",pL); 4 L.length=0; 5 pL->length=0; 6 return 1; 7 }
说明:
1、在上面顺序表操作函数中,有的入参是SqList类型的,有的是SqList*类型的,两者是有区别的,通过clearList()函数进行说明;
2、入参有两种类型,这是为了测试在函数内部,处理的顺序表在内存中的位置是什么,在函数内部,会把顺序表的位置以%d的方式打印出来;同时在调用函数之前,会把传入的入参顺序表L的地址打印出来;
通过测试发现,如果入参为SqList L,在函数内部地址同外部的顺序表L地址不相同,如果入参为SqList *pL,在函数内部地址同外部的顺序表L地址相同;当入参为SqList L时,执行L.length=0;无效,根本没有将顺序表的唱的长度置为0;
3、综上所述,如果要修改顺序表中的值(包括长度,以及各个元素的值),比如创建顺序表、插入元素、删除元素等等操作,是对顺序表内的数据有改动的,就要传入SqList *类型的入参,否则达不到修改的目的;【这其实就是函数的值传递和地址传递】