数据结构中线性表的顺序式表示的基本操作函数
线性表的基本操作共有十二个。我们通过对线性表基本操作的有机组合,可以处理较为复杂的线性表。
一、初始化顺序线性表——构造一个空的顺序线性表
1 void InitList(SqList &L) 2 { 3 L.elem = (ElemType*)malloc(LIST_INIT_SIZE *sizeof(ELemType));//malloc函数来分配存储空间 4 if(!L.elem)//分配存储失败 5 { 6 exit(OVERFLOW); 7 } 8 L.length = 0;//空表的长度为0 9 L.listsize = LIST_INIT_SIZE;//初始的存储容量等于LIST_INIT_SIZE 10 }
顺序表初始化的基本步骤:
1、开辟存储空间,使用malloc函数,个数为LIST_INIT_SIZE,每个存储元素的大小为sizeof(ElemType);
2、初始化当前的表长为0;
3、初始的存储容量为LIST_INIT_SIZE
二、销毁顺序线性表
1 void DestoryList(SqList &L) 2 { 3 free(L.elem);//释放L.elem所指的存储空间 4 L.elem = NULL;//L.elem不再指向任何存储单元 5 L.length = 0;//顺序表的长度置零 6 L.listsize = 0;//顺序表的大小也置为零 7 }
销毁顺序表的步骤:
1、用free(L.elem)释放指针所指的存储空间;
2、指针不指向任何东西,即L.elem = NULL
3、将顺序表的表长和存储容量都置为零
三、重置顺序线性表为空
1 void ClearList(SqList &L) 2 { 3 L.length = 0;//直接把当前表长置为零,判断元素的的个数就是通过当前表长来判断的 4 }
注:顺序表的当前表长已经置零,如果要存储数据的话,仍然从elem[0]开始存储,新的数据将直接覆盖原来指针中所包含的数据
四、判断顺序线性表是否为空
1 Status ListEmpty(SqList L) 2 { 3 if(L.Length == 0)//如果是零返回TRUE,这里是宏定义,TRUEdai表1,FALSE 代表0 4 { 5 return TRUE; 6 } 7 else 8 { 9 return FALSE; 10 } 11 ]
注:Status 也是宏定义,这里代表的就是 int 整形
五、求顺序线性表中元素的个数
1 Status ListLength(SqList L) 2 { 3 return L.length;//L.length中的值代表的就是顺序表中元素的个数 4 }
六、获取顺序线性表中第i个元素的值
1 Status GetElem(SqList L,int i,ElemType &e) 2 { 3 if(i < 1 || i > L.length)//i 不在L的范围之内 4 { 5 return ERROR; 6 } 7 e = *(L.elem + i - 1);//将L的第i个元素值赋给e 8 }
七、确定顺序表中与元素e满足compare()函数的关系
1 int LocateElem(SqList L,ElemType e,Status *(compare)(ElemType ,ElemType)) 2 { 3 int i = 1;//i的初值为第一个元素的位序 4 ElemType *p = L.elem;//p指向第一个元素 5 while(i <= L.length && !compare(*p ++,e))//i没有超出表的范围并且未找到满足关系的元素 6 { 7 i ++; 8 } 9 if(i <= L.length)//找到满足关系的元素 10 { 11 return i;//返回其位序 12 } 13 else//未找到满足关系的数据 14 { 15 return 0; 16 } 17 }
注:compare()是一个函数,在其中可以定义两个元素的某种关系,比如相等、二倍等等。
八、cur_e是L中的元素,且不是第一个,用pre_e返回它的前驱
1 Status PriorElem(SqList L, ElemType cur_e, ElemType &pre_e)// 若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,否则操作失败,pre_e无定义 2 { 3 int i = 2;//从第二个元素开始 4 ElemType *p = L.elem + 1;//p指向第二个元素 5 while (i < L.length && *p != cur_e)//i未超出表的范围,且未找到cure_e 6 { 7 p++;//p 指向下一个元素 8 i++;//计数加一 9 } 10 if (i > L.length)//到表结束还没有找到cure_e的元素 11 { 12 return ERROR; 13 } 14 else 15 { 16 pre_e = *--p;//如果成功p指向钱一个元素 17 return OK; 18 } 19 }
九、cur_e是L中的元素,且不是最后一个,用next_e返回它的前驱
1 Status NexElem(SqList L, ElemType cur_e, ElemType &next_e)//若cur_e是L中的元素,且不是最后一个,则用next_e返回他的后继,否则操作失败,无定义 2 { 3 int i = 1;//从第一个元素开始 4 ElemType *p = L.elem;//p指向第一个元素 5 while (i < L.length && *p != cur_e)//i未找到值为cur_e的元素 6 { 7 p++;//p 指向下一个元素 8 i++;//计数加一 9 } 10 if (i == L.length)//到表尾还么有找到元素 11 { 12 return ERROR; 13 } 14 else 15 { 16 next_e = *++p;//p指向下一个元素,将所指的元素的值赋给next_e 17 return OK; 18 } 19 }
十、插入元素
1 Status ListInsert(SqList &L, int i, ElemType e)//在L中第i个位置插入e 2 { 3 ElemType *newbase, *q, *p; 4 if (i < 1 || i > L.length) 5 { 6 return ERROR; 7 } 8 if (L.length == L.listsize) //存储空间已满 9 { 10 newbase = (ElemType *)realloc(L.elem, (L.listsize + LIST_INCREMENT)*sizeof(ElemType)); 11 if (!newbase) 12 { 13 exit(OVERFLOW); 14 } 15 L.elem = newbase;//新的基址赋给L.elem 16 L.listsize += LIST_INCREMENT;//增加存储容量 17 } 18 q = L.elem + i - 1; 19 for (p = L.elem + L.length - 1; p >= q; --p)//移位 20 { 21 *(p + 1) = *p; 22 } 23 *q = e;//插入e 24 L.length++;//表长加一 25 return OK; 26 }
十一、删除元素
1 Status ListDelete(SqList &L, int i, ElemType &e)//删除第i个元素,并用e返回其值 2 { 3 ElemType *p, *q; 4 if (i < 1 || i > L.length)//i值不合法 5 { 6 return ERROR; 7 } 8 p = L.elem + i - 1;//p为被删除元素的位置 9 e = *p;//被删除元素值赋给e 10 q = L.elem + L.length - 1;//q为表尾元素的位置 11 for (p++; p <= q; p++) 12 { 13 *(p - 1) = *p; 14 } 15 L.length--; 16 return OK; 17 }
十二、依次对每个数据元素调用visit()函数
1 void ListTraverse(SqList L, void(*visit)(ElemType)) 2 { 3 ElemType *p = L.elem; 4 int i; 5 for (i = 1; i <= L.length; i++) 6 { 7 visit(*p++); 8 } 9 printf("\n"); 10 }
我登高只为了看的更远,如果看到的景色不如人意,我将选择继续攀登!