数据结构笔记(二)--- 顺序实现线性表

线性结构的顺序实现----设计

一、设计数据类型(D)

假设数据类型为 int

二、设计数据关系(S)

线性,内存连续

三、设计基本操作(P)

//1、构造一个空的顺序线性表L
void InitList(pSqList L);
//2、判断L是否为空
bool ListIsEmputy(pSqList pL);
//3、判断L是否为满
bool ListIsFull(pSqList pL);
//4、在L的末尾追加新的数据元素e,当线性表满时会自动扩容
bool ListAdd(pSqList pL, ElemType e);
//5、遍历输出线性表所有元素 
void ListTraverse(pSqList pL);
//6、在指定位置第pos个元素前插入元素,当线性表满时会自动扩容
bool ListInsert(pSqList pL,int pos, ElemType e);
//7、将L重置为空表
void ClearList(pSqList pL);
//8、返回L中数据元素个数
int ListLength(pSqList pL);
//9、获取顺序线性表第i个数据元素的值
bool GetElem(pSqList pL,int i,ElemType * e);
//10、查找满足相应条件的元素,条件由函数指针compare 指向的函数决定,e是传入指针函数中的值
int LocateElem(pSqList pL,ElemType e,bool(*compare)(ElemType,ElemType));
//11、返回顺序线性表中指定第一个值为cur_e元素的前驱pre_e
bool PriorElem(pSqList pL,ElemType cur_e,ElemType * pre_e);
//12、返回顺序线性表中指定第一个值为cur_e元素的后继next_e
bool NextElem(pSqList pL,ElemType cur_e,ElemType * next_e);
//13、删除L的第i个数据元素,并用e返回其值,L的长度减1
bool ListDelete(pSqList pL,int i,ElemType *e); 
//14、修改第i个元素的值
bool  ListModifyElem(pSqList pL,int i,ElemType e);
//15、元素升序排序
void ListSort(pSqList pL);
//16、销毁顺序线性表
void DestroyList(pSqList pL)


线性结构的顺序实现----代码

一、设计数据类型(D)的实现

typedef int ElemType; /* 定义抽象数据类型ElemType为整型 */

//设计一个保存序列信息的头
typedef struct SqList
 {
   ElemType * elem; // 存储空间基址
   int length; // 当前长度(有效元素个数)
   int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
 }SqList,* pSqList;

二、设计数据关系(S)

线性,内存连续代码实现
即顺序线性表
数据结构笔记(二)--- 顺序实现线性表_第1张图片

//使用malloc函数申请连续的内存空间
L->elem=(ElemType*)malloc(listsize*sizeof(ElemType));

三、设计基本操作(P)

1、InitList(&L)
{// 初始条件:无
// 操作结果:构造一个空的顺序线性表L
}

  void InitList(pSqList L) //
 { // 操作结果:构造一个空的顺序线性表L
   int listsize;
   printf("请输入要创建的线性数据的长度 listsize: ");
   scanf("%d",listsize);
   L->length = 0;
   L->elem=(ElemType*)malloc(listsize*sizeof(ElemType));
   if(!L->elem)//地址为空则存储分配失败
     exit(-1); // 结束程序
   L->length=0; // 空表长度为0
   L->listsize=listsize; // 初始存储容量
 }

函数介绍
新内存的首地址 = realloc (原内存的首地址,要调整到多大)
realloc调整malloc分配动态内存,即放大或者缩小原动态内存的大小,放大和缩小均不改变原内存的值,缩小会丢失值。

#include 
char *p;
p = (char * ) malloc (10);//分配一块10个字节内存
q = (char * ) realloc (p,20);//尝试将malloc分配的一块10个字节内存调整到20个字节
//1.如果 当前连续内存块足够 realloc 的话,只是将p所指向的空间扩大,并返回p的指针地址。 这个时候 q 和 p 指向的地址是一样的。
//2.如果 当前连续内存块不够长度,realloc会再找一个足够长的地方,分配一块新的内存,返回新的内存的首地址给q,并将 p指向的内容 copy到 q,并将p所指向的内存空间删除

2、判断顺序线性表L是否为空
bool ListIsEmputy(pSqList pL)

//2、判断L是否为空
bool ListIsEmputy(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:判断L是否为空
	
	if(pL->length==0)
		return true;
	else
		return false;
}

3、判断顺序线性表L是否为满
bool ListIsFull(pSqList pL)

//3、判断L是否为满
bool ListIsFull(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:判断L是否为满
	
	if(pL->length==pL->listsize)
		return true;
	else
		return false;
}

4、在L的末尾追加新的数据元素e,当线性表满时会自动扩容
bool ListAdd(pSqList pL, ElemType e)

数据结构笔记(二)--- 顺序实现线性表_第2张图片

//4、在L的末尾追加新的数据元素e,当线性表满时会自动扩容
bool ListAdd(pSqList pL, ElemType e) 
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:在L的末尾追加新的数据元素e
	ElemType *  newbase;
	if(ListIsFull(pL))
	{
		newbase =(ElemType *)realloc(pL->elem,(pL->listsize+pL->list_increment)*sizeof(ElemType));
	
		if(!newbase)
		 //尝试将之前malloc分配的内存调整到指定长度
		 //1.如果 当前连续内存块足够 realloc 的话,只是将pL->elem所指向的空间扩大,
		 //并返回newbase的指针地址。 这个时候 newbase 和 pL->elem 指向的地址是一样的。
		 //2.如果 当前连续内存块不够长度,再找一个足够长的地方,
		 //分配一块新的内存,newbase,并将pL->elem指向的内容 copy到 newbase,返回 newbase。并将pL->elem所指向的内存空间删除
		{		
			printf("存储分配失败,程序退出!\n");
			exit(-1); // 存储分配失败
		}
		printf("-------已扩容!----------\n");
		pL->elem = newbase; // 新基址
		pL->listsize += pL->list_increment; // 增加存储容量
	}
	pL->elem[pL->length] = e;
	pL->length++;
	return true;
 }

5、遍历输出顺序线性表所有元素
void ListTraverse(pSqList pL)

//5、遍历输出顺序线性表所有元素 
void ListTraverse(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:遍历输出顺序线性表所有元素

	int i;
	for(i = 0; i<pL->length; i++)
	{
		printf("%d   ",pL->elem[i]);
	}
		printf("\n");
}

6、在指定位置第pos个元素前插入元素,当线性表满时会自动扩容
bool ListInsert(pSqList pL,int pos, ElemType e)

数据结构笔记(二)--- 顺序实现线性表_第3张图片

//6、在指定位置第pos个元素前插入元素,当线性表满时会自动扩容
bool ListInsert(pSqList pL,int pos, ElemType e) 
{   // 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L)+1
    // 操作结果:在L中第pos个位置之前插入新的数据元素e,L的长度加1
    ElemType * newbase,*q,*p;
    if(pos<1||pos>pL->length+1) // pos值不合法
    return false;

    if(ListIsFull(pL)) // 当前存储空间已满,增加分配
    {
		if(!(newbase=(ElemType *)realloc(pL->elem,(pL->listsize+pL->list_increment)*sizeof(ElemType))))
     	//尝试将之前malloc分配的内存调整到指定长度
		{
			exit(-1); // 存储分配失败
		}
        pL->elem = newbase; // 新基址
        pL->listsize += pL->list_increment; // 增加存储容量
	    printf("-------已扩容!----------\n");
    }
    q=pL->elem+pos-1; // q为插入位置
    for(p=pL->elem+pL->length-1; p>=q; --p) // 插入位置及之后的元素右移
    {
	    *(p+1)=*p;
    }
    *q=e; // 插入e
    ++pL->length; // 表长增1
    return true;
}

7、将L重置为空表
void ClearList(pSqList pL)

//7、将L重置为空表
void ClearList(pSqList pL)
{   // 初始条件:顺序线性表L已存在。
    //操作结果:将L重置为空表
	pL->length=0;
}

8、返回L中数据元素个数
int ListLength(pSqList pL)

//8、返回L中数据元素个数
int ListLength(pSqList pL)
{   // 初始条件:顺序线性表L已存在。
    //操作结果:返回L中数据元素个数
	return pL->length;
}

9、获取顺序线性表第i个数据元素的值
bool GetElem(pSqList pL,int i,ElemType * e)

//9、获取顺序线性表第i个数据元素的值
bool GetElem(pSqList pL,int i,ElemType * e)
{   // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)。
    //操作结果:用e返回L中第i个数据元素的值
    //注意形参出现ElemType &e的含义是直接将实参e给传过来,而不再是复制一份过来,在函数中可以直接修改其值,
    //其结果相当于传入地址进行操作,在这里我们使用传地址的方式修改e
    if(i<1||i>pL->length)
    {
    	   return false;
    }   
    *e = *(pL->elem+i-1);
    return true;
}

*10、查找满足相应条件的元素,条件由函数指针compare 指向的函数决定
int LocateElem(pSqList pL,ElemType e,bool(compare)(ElemType,ElemType))

//10、查找满足相应条件的元素,条件由函数指针compare 指向的函数决定
int LocateElem(pSqList pL,ElemType e,bool(*compare)(ElemType,ElemType))
{   // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
    // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
    //           若这样的数据元素不存在,则返回值为0。
    //bool(*compare)(ElemType,ElemType)表示变量compare是一个指向返回值是bool,形参为(ElemType,ElemType)的函数指针 
    //假设定义一个函数 bool f(ElemType,ElemType); compare = f 那么  compare()就代表函数f()
    ElemType * p;
    int i=1; // i的初值为第1个元素的位序
    p=pL->elem; // p的初值为第1个元素的存储位置
    while(i <= pL->length && !compare(*p++,e)) //不满足关系一直循环直到遍历所有有效元素
      ++i;
    if(i<=pL->length)//跳出循环1、元素未遍历完找到了满足条件的元素 2、元素遍历完毕没有满足条件的。
      return i;
    else
      return 0;
}
//第三个参数(相应条件)示例,传参是只需要传递函数名即可
 bool equal(ElemType c1,ElemType c2)
 { // 判断两个元素是否相等
   if(c1==c2)
     return true;
   else
     return false;
 }

11、返回顺序线性表中指定第一个值为cur_e元素的前驱
bool PriorElem(pSqList pL,ElemType cur_e,ElemType * pre_e)

//11、返回顺序线性表中指定第一个值为cur_e元素的前驱
bool PriorElem(pSqList pL,ElemType cur_e,ElemType * pre_e)
{   // 初始条件:顺序线性表L已存在
    // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
    //           否则操作失败,pre_e无定义
    int i=2;
    ElemType * p=pL->elem+1;
    while(i<=pL->length&& *p != cur_e)//不满足关系一直循环直到遍历所有有效元素
    {
      p++;
      i++;
    }
    if(i>pL->length)
      return false; // 操作失败
    else
    {
      *pre_e = *--p;//将指针p回退一步找到前驱元素返回
      return true;
    }
}

12、返回顺序线性表中指定第一个值为cur_e元素的后继next_e
bool NextElem(pSqList pL,ElemType cur_e,ElemType * next_e)

//12、返回顺序线性表中指定第一个值为cur_e元素的后继next_e
bool NextElem(pSqList pL,ElemType cur_e,ElemType * next_e)
{   // 初始条件:顺序线性表L已存在
    // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
    //           否则操作失败,next_e无定义
    int i=2;
    ElemType * p=pL->elem+1;
    while(i<=pL->length&& *p != cur_e)//不满足关系一直循环直到遍历所有有效元素
    {
      p++;
      i++;
    }
    if(i>pL->length)
      return false; // 操作失败
    else
    {
      *next_e = *++p;//将指针p回退一步找到前驱元素返回
      return true;
    }
}

13、删除L的第i个数据元素,并用e返回其值,L的长度减1
bool ListDelete(pSqList pL,int i,ElemType * e)

数据结构笔记(二)--- 顺序实现线性表_第4张图片

//13、删除L的第i个数据元素,并用e返回其值,L的长度减1
bool ListDelete(pSqList pL,int i,ElemType * e) 
{   // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
    // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
    ElemType *p,*q;
    if(ListIsEmputy(pL)) // 顺序线性表为空
      return false;
    if(i<1||i>pL->length) // i值不合法
      return false;
    q=pL->elem+i-1; // q为被删除元素的位置
    *e = *q; // 被删除元素的值赋给e
    p=pL->elem+pL->length-1; // 表尾元素的位置
    for(++q; q<=p; ++q)	//q右移 
      *(q-1)=*q;	  // 被删除元素之后的元素左移
    pL->length--; // 表长减1
    return true;
}

14、修改第i个元素的值
bool ListModifyElem(pSqList pL,int i,ElemType e)

数据结构笔记(二)--- 顺序实现线性表_第5张图片

//14、修改第i个元素的值
bool  ListModifyElem(pSqList pL,int i,ElemType e)
{
	if(i<1 || i>pL->length)//i值不合法
      return false;
	pL->elem[i-1] = e;
	return true;
}

15、元素升序排序(选择排序)
void ListSort(pSqList pL)

//15、元素升序排序(选择排序)
void ListSort(pSqList pL)
{
	int i,j;
	ElemType temp;
	for(i = 0; i<pL->length; ++i)
	{
		for(j = i+1; j<pL->length; ++j)
		{
			if(pL->elem[i]>pL->elem[j])
			{
				temp = pL->elem[i];
				pL->elem[i] = pL->elem[j];
				pL->elem[j] = temp;
			}	
		}

	}
}

16、销毁顺序线性表
void DestroyList(pSqList pL)

//16、销毁顺序线性表
void DestroyList(pSqList pL)
{ // 初始条件:顺序线性表L已存在。
   //操作结果:销毁顺序线性表L
    free(pL->elem);//释放pL->elem指向的动态分配的内存空闲
    pL->elem=NULL;//让pL指向为空
    pL->length=0;//恢复初始值
    pL->listsize=0;//恢复初始值
}

整体C语言代码

# include
# include
# include

typedef int ElemType; /* 定义抽象数据类型ElemType为整型 */

//设计一个保存序列信息的头
typedef struct SqList
 {
   ElemType * elem; // 存储空间基址
   int length; // 当前长度(有效元素个数)
   int listsize; // 当前分配的存储容量(以sizeof(ElemType)为单位)
   int list_increment;//当线性表满了以后,需要扩充时,每次扩充2个ElemType单位
 }SqList,* pSqList;

//1
 bool equal(ElemType c1,ElemType c2)
 { // 判断是否相等的函数
   if(c1==c2)
     return true;
   else
     return false;
 }


//1、构造一个空的顺序线性表L
void InitList(pSqList L);
//2、判断L是否为空
bool ListIsEmputy(pSqList pL);
//3、判断L是否为满
bool ListIsFull(pSqList pL);
//4、在L的末尾追加新的数据元素e,当线性表满时会自动扩容
bool ListAdd(pSqList pL, ElemType e);
//5、遍历输出线性表所有元素 
void ListTraverse(pSqList pL);
//6、在指定位置第pos个元素前插入元素,当线性表满时会自动扩容
bool ListInsert(pSqList pL,int pos, ElemType e);
//7、将L重置为空表
void ClearList(pSqList pL);
//8、返回L中数据元素个数
int ListLength(pSqList pL);
//9、获取顺序线性表第i个数据元素的值
bool GetElem(pSqList pL,int i,ElemType * e);
//10、查找满足相应条件的元素,条件由函数指针compare 指向的函数决定,e是传入指针函数中的值
int LocateElem(pSqList pL,ElemType e,bool(*compare)(ElemType,ElemType));
//11、返回顺序线性表中指定第一个值为cur_e元素的前驱pre_e
bool PriorElem(pSqList pL,ElemType cur_e,ElemType * pre_e);
//12、返回顺序线性表中指定第一个值为cur_e元素的后继next_e
bool NextElem(pSqList pL,ElemType cur_e,ElemType * next_e);
//13、删除L的第i个数据元素,并用e返回其值,L的长度减1
bool ListDelete(pSqList pL,int i,ElemType *e); 
//14、修改第i个元素的值
bool  ListModifyElem(pSqList pL,int i,ElemType e);
//15、元素升序排序
void ListSort(pSqList pL);
//16、销毁顺序线性表
void DestroyList(pSqList pL)


void main()
{
	ElemType e , pre_e, next_e;//e接收GetElem返回的元素,pre_e接收PriorElem返回的元素,next_e接收NextElem返回的元素
    SqList La;
    InitList(&La);
    if(ListIsEmputy(&La))
    {
 	    printf("线性表为空\n");
    }
    else
	    printf("线性表不为空\n");

    if( ListAdd(&La, 5))
	{
	    printf("追加成功!\n");
    }
    else
	    printf("追加失败!\n");


    ListAdd(&La, 2);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListAdd(&La, 3);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListAdd(&La, 7);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListAdd(&La, 6);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);

    ListTraverse(&La);
	ListInsert(&La,2, 99);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListInsert(&La,1, 88);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListInsert(&La,1, 77);
	printf("线性表长度 %d   有效元素个数 %d\n",La.listsize,La.length);
	ListTraverse(&La);
	GetElem(&La,5,&e);
	printf("La第5个元素是 %d\n",e);
	printf("La中第 %d 个元素满足条件\n",LocateElem(&La,2,equal));

	if(PriorElem(&La,2,&pre_e))
	   printf("顺序线性表中指定第一个值为2的元素的前驱pre_e = %d\n",pre_e);
    else
	   printf("操作失败!\n");  

    if(NextElem(&La,2,&next_e))
	   printf("顺序线性表中指定第一个值为2的元素的后继next_e = %d\n",next_e);
    else
	   printf("操作失败!\n"); 

	ListDelete(&La,6,&e);
	ListTraverse(&La);
	ListModifyElem(&La,6,101);
	ListTraverse(&La);
	ListSort(&La);
	ListTraverse(&La);

	



	printf("----------清空线性表----------\n");
	ClearList(&La);
	if(ListIsEmputy(&La))
   {
	   printf("线性表为空\n");
   }
   else
	   printf("线性表不为空\n");  
}


//1、构造一个空的顺序线性表L
void InitList(pSqList pL) //
{   // 操作结果:构造一个空的顺序线性表L
    int listsize;
    printf("请输入要创建的顺序线性表的长度 listsize: ");
    scanf("%d", &listsize);
    pL->elem = (ElemType *)malloc(listsize*sizeof(ElemType));
    if(!pL->elem)//地址为空则存储分配失败
    exit(-1); // 结束程序
    pL->length=0; // 空表长度为0
    pL->listsize=listsize; // 初始存储容量
    pL->list_increment = 2;
    //printf("%d",pL->list_increment); 
}


//2、判断L是否为空
bool ListIsEmputy(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:判断L是否为空
	
	if(pL->length==0)
		return true;
	else
		return false;
}


//3、判断L是否为满
bool ListIsFull(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:判断L是否为满
	
	if(pL->length==pL->listsize)
		return true;
	else
		return false;
}


//4、在L的末尾追加新的数据元素e,当线性表满时会自动扩容
bool ListAdd(pSqList pL, ElemType e) 
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:在L的末尾追加新的数据元素e
	ElemType *  newbase;
	if(ListIsFull(pL))
	{
		newbase =(ElemType *)realloc(pL->elem,(pL->listsize+pL->list_increment)*sizeof(ElemType));
	
		if(!newbase)
		 //尝试将之前malloc分配的内存调整到指定长度
		 //1.如果 当前连续内存块足够 realloc 的话,只是将pL->elem所指向的空间扩大,
		 //并返回newbase的指针地址。 这个时候 newbase 和 pL->elem 指向的地址是一样的。
		 //2.如果 当前连续内存块不够长度,再找一个足够长的地方,
		 //分配一块新的内存,newbase,并将pL->elem指向的内容 copy到 newbase,返回 newbase。并将pL->elem所指向的内存空间删除
		{		
			printf("存储分配失败,程序退出!\n");
			exit(-1); // 存储分配失败
		}
		printf("-------已扩容!----------\n");
		pL->elem = newbase; // 新基址
		pL->listsize += pL->list_increment; // 增加存储容量
	}
	pL->elem[pL->length] = e;
	pL->length++;
	return true;
 }


//5、遍历输出顺序线性表所有元素 
void ListTraverse(pSqList pL)
{
    // 初始条件:顺序线性表L已存在,
    // 操作结果:遍历输出顺序线性表所有元素

	int i;
	for(i = 0; i<pL->length; i++)
	{
		printf("%d   ",pL->elem[i]);
	}
		printf("\n");
}



//6、在指定位置第pos个元素前插入元素,当线性表满时会自动扩容
bool ListInsert(pSqList pL,int pos, ElemType e) 
{   // 初始条件:顺序线性表L已存在,1≤pos≤ListLength(L)+1
    // 操作结果:在L中第pos个位置之前插入新的数据元素e,L的长度加1
    ElemType * newbase,*q,*p;
    if(pos<1||pos>pL->length+1) // pos值不合法
    return false;

    if(ListIsFull(pL)) // 当前存储空间已满,增加分配
    {
		if(!(newbase=(ElemType *)realloc(pL->elem,(pL->listsize+pL->list_increment)*sizeof(ElemType))))
     	//尝试将之前malloc分配的内存调整到指定长度
		{
			exit(-1); // 存储分配失败
		}
        pL->elem = newbase; // 新基址
        pL->listsize += pL->list_increment; // 增加存储容量
	    printf("-------已扩容!----------\n");
    }
    q=pL->elem+pos-1; // q为插入位置
    for(p=pL->elem+pL->length-1; p>=q; --p) // 插入位置及之后的元素右移
    {
	    *(p+1)=*p;
    }
    *q=e; // 插入e
    ++pL->length; // 表长增1
    return true;
}


//7、将L重置为空表
void ClearList(pSqList pL)
{   // 初始条件:顺序线性表L已存在。
    //操作结果:将L重置为空表
	pL->length=0;
}


//8、返回L中数据元素个数
int ListLength(pSqList pL)
{   // 初始条件:顺序线性表L已存在。
    //操作结果:返回L中数据元素个数
	return pL->length;
}

//9、获取顺序线性表第i个数据元素的值
bool GetElem(pSqList pL,int i,ElemType * e)
{   // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)。
    //操作结果:用e返回L中第i个数据元素的值
    //注意形参出现ElemType &e的含义是直接将实参e给传过来,而不再是复制一份过来,在函数中可以直接修改其值,
    //其结果相当于传入地址进行操作,在这里我们使用传地址的方式修改e
    if(i<1||i>pL->length)
    {
    	   return false;
    }   
    *e = *(pL->elem+i-1);
    return true;
}


//10、查找满足相应条件的元素,条件由函数指针compare 指向的函数决定
int LocateElem(pSqList pL,ElemType e,bool(*compare)(ElemType,ElemType))
{   // 初始条件:顺序线性表L已存在,compare()是数据元素判定函数(满足为1,否则为0)
    // 操作结果:返回L中第1个与e满足关系compare()的数据元素的位序。
    //           若这样的数据元素不存在,则返回值为0。
    //bool(*compare)(ElemType,ElemType)表示变量compare是一个指向返回值是bool,形参为(ElemType,ElemType)的函数指针 
    //假设定义一个函数 bool f(ElemType,ElemType); compare = f 那么  compare()就代表函数f()
    ElemType * p;
    int i=1; // i的初值为第1个元素的位序
    p=pL->elem; // p的初值为第1个元素的存储位置
    while(i <= pL->length && !compare(*p++,e)) //不满足关系一直循环直到遍历所有有效元素
      ++i;
    if(i<=pL->length)//跳出循环1、元素未遍历完找到了满足条件的元素 2、元素遍历完毕没有满足条件的。
      return i;
    else
      return 0;
}


//11、返回顺序线性表中指定第一个值为cur_e元素的前驱
bool PriorElem(pSqList pL,ElemType cur_e,ElemType * pre_e)
{   // 初始条件:顺序线性表L已存在
    // 操作结果:若cur_e是L的数据元素,且不是第一个,则用pre_e返回它的前驱,
    //           否则操作失败,pre_e无定义
    int i=2;
    ElemType * p=pL->elem+1;
    while(i<=pL->length&& *p != cur_e)//不满足关系一直循环直到遍历所有有效元素
    {
      p++;
      i++;
    }
    if(i>pL->length)
      return false; // 操作失败
    else
    {
      *pre_e = *--p;//将指针p回退一步找到前驱元素返回
      return true;
    }
}


//12、返回顺序线性表中指定第一个值为cur_e元素的后继next_e
bool NextElem(pSqList pL,ElemType cur_e,ElemType * next_e)
{   // 初始条件:顺序线性表L已存在
    // 操作结果:若cur_e是L的数据元素,且不是最后一个,则用next_e返回它的后继,
    //           否则操作失败,next_e无定义
    int i=2;
    ElemType * p=pL->elem+1;
    while(i<=pL->length&& *p != cur_e)//不满足关系一直循环直到遍历所有有效元素
    {
      p++;
      i++;
    }
    if(i>pL->length)
      return false; // 操作失败
    else
    {
      *next_e = *++p;//将指针p回退一步找到前驱元素返回
      return true;
    }
}

//13、删除L的第i个数据元素,并用e返回其值,L的长度减1
bool ListDelete(pSqList pL,int i,ElemType * e) 
{   // 初始条件:顺序线性表L已存在,1≤i≤ListLength(L)
    // 操作结果:删除L的第i个数据元素,并用e返回其值,L的长度减1
    ElemType *p,*q;
    if(ListIsEmputy(pL)) // 顺序线性表为空
      return false;
    if(i<1||i>pL->length) // i值不合法
      return false;
    q=pL->elem+i-1; // q为被删除元素的位置
    *e = *q; // 被删除元素的值赋给e
    p=pL->elem+pL->length-1; // 表尾元素的位置
    for(++q; q<=p; ++q)	//q右移 
      *(q-1)=*q;	  // 被删除元素之后的元素左移
    pL->length--; // 表长减1
    return true;
}

//14、修改第i个元素的值
bool  ListModifyElem(pSqList pL,int i,ElemType e)
{
	if(i<1 || i>pL->length)//i值不合法
      return false;
	pL->elem[i-1] = e;
	return true;
}
//15、元素升序排序(选择排序)
void ListSort(pSqList pL)
{
	int i,j;
	ElemType temp;
	for(i = 0; i<pL->length; ++i)
	{
		for(j = i+1; j<pL->length; ++j)
		{
			if(pL->elem[i]>pL->elem[j])
			{
				temp = pL->elem[i];
				pL->elem[i] = pL->elem[j];
				pL->elem[j] = temp;
			}	
		}

	}
}

//16、销毁顺序线性表
void DestroyList(pSqList pL)
{ // 初始条件:顺序线性表L已存在。
   //操作结果:销毁顺序线性表L
    free(pL->elem);//释放pL->elem指向的动态分配的内存空闲
    pL->elem=NULL;//让pL指向为空
    pL->length=0;//恢复初始值
    pL->listsize=0;//恢复初始值
}


你可能感兴趣的:(数据结构)