一.基本运算的实现
1.建立顺序表
void CreateList(SqList * & L,ElemType a[],int n) //由a中的n个元素建立顺序表 { int i = 0,k = 0; //k表示L中的元素个数,初始值为0 L = (SqList *)malloc(sizeof(SqList)); //分配线性表的空间 while(i < n) { L->data[k] = a[i]; //将元素a[i]存放到L中 k++; i++; } L->length = k; //设置L的长度K }
/* malloc(sizeof(数据类型))
功能:分配存储空间
返回值:所分配的内存区地址 */
2.初始化线性表
void InitList(SqList * & L) { L = (SqList * )mallc(sizeof(SqList); //分配存放线性表的空间 L -> lenght = 0; }
/* 1.&代表引用型指针,类似于地址共享。需要对主函数的值进行修改时,就要用&引用。
2.(SqList *)为强制转换,强制malloc分配为SqList的空间大小。 */
3.销毁线性表
void DestroyList(SqList * & L) { free(L); //释放L所指的顺序表空间 }
// 若不进行销毁,尽管系统会自动释放顺序表指针变量L,但不会自动释放L所指向的存储空间,如此可能会造成内存泄漏。
4.判断线性表是否为空表
bool ListEmpty(SqList * L) { return(L -> length == 0); }
// 这里的“空”指空闲,不等于空白。只要L -> length == 0即为空表,不管表中是否有数据。
5.求线性表的长度
int ListLength(SqList * L) { return(L -> length); }
6.输出线性表
void DispList(SqList * L) { int i = 0; for(i=0;ilength;i++) printf("%d ",L -> data[i]); printf("\n"); }
7.求线性表中的第i个元素的值
bool GetElem(SqList * L,int i,ElemType &e) { if(i<1 || i>L -> length) return false; e = L -> data[i-1]; return true; }
8.查找第一个与e相等的元素
int LocateElem(SqList * L,ElemType e) { int i = 0; while(ilength && L -> data[i]!=e) i++; if(i>=L -> length) return 0; else return i+1; }
9.在第i个位置上插入新数据
void ListInsert(SqList * & L,int i,ElemType e) { int j; if(i<1 || i>L -> length+1) return false; i--; for(j=L -> length;j>i;j--) L -> data[j] = L ->data[j-1]; L -> data[i] = e; L -> length++; return true; }
10.删除第i个数据元素
bool ListDelete(SqList * & L,int i,ElemType &e) { int j; if(i<1 || i>L -> length) return false; i--; e = L -> data[i]; for(j=i;jlength-1;j++) L -> data[j] = L -> data[j+1]; L -> length--; return true; }
二.应用示例
1.假设一个线性表采用顺序表表示,设计一个算法,删除其中所有制等于x的元素。要求算法的时间复杂度为O(n),空间复杂度为O(1).
//解法一 void delnode1(SqList * & L,ElemType x) { int k=0,i; //k记录不等于x的元素个数,即要插入到L中的元素个数 for(i=0;ilength;i++) if(L -> data[i] != x) //若当前元素不为x,将其插入到L中 { L -> data[k] = L -> data[i]; k++; } L -> length = k; } //解法二 void delnode2(SqList * & L,ElemType x) { int k=0,i=0; //k记录等于x的元素个数 while(i length) { if(L -> data[i]==x) //当前元素为x时k增1 k++; else //当前元素不为x时将其前移k个位置 L -> data[i-k] = L-> data[i]; i++; } L -> length -= k; }
2.有一个顺序表L,假设元素类型ElemType为整型,设计一个尽可能高效的算法,以第一个元素为分界线(基准),将所有小于等于它的元素一道该基准的前面,将所有大于它的元素移到该基准的后面。
//解法一 int partiton1(SqList * & L) { int i=0,j=L->length-1; //以data[0]为基准 ElemType pivot = L->data[0]; while(i < j) //从区间两端交替向中间扫描,直到i=j为止 { while(idata[j]>pivot) //从右向左扫描,找一个小于等于pivot的元素 j--; while(i data[i]<=pivot) //从左向右扫描,找一个大于pivot的元素 i++; if(i < j) swap(L->data[i],L->data[j]); } swap(L->data[0],L->data[i]); } //解法二 void partition2(SqList * & L) { int i=0,j=L->length-1; ElemType pivot = L->data[0]; //以data[0]为基准 while(i < j) //从区间两端交替向中间扫描,直到i=j为止 { while(i data[j]>pivot) j--; //从右向左扫描,找一个小于等于pivot的data[j] L->data[i] = L->data[j]; //找到这样的data[j],放入data[i]处 while(i data[i]<=pivot) i++; //从左向右扫描,找一个大于pivot的data[i] L->data[j] = L->data[i]; //找到这样的data[i],放入data[j]处 } L->data[i] = pivot; }
3.有一个顺序表L,假设元素类型ElemType为整型,设计一个尽可能高效的算法,将所有奇数移动到偶数的前面。
//解法一 void move1(SqList * & L) { int i=0,j=L->length-1; while(i < j) { while(idata[j]%2==0) j--; //从右向左扫描,找一个奇数元素 while(i data[i]%2==1) i++; //从左向右扫描,找一个偶数 if(i < j) swap(L->data[i],L->data[j]); } } //解法二 void move2(SqList * & L) { int i=-1,j; for(j=0;j<=L->length-1;j++) if(L->data[j]%2 == 1) { i++; //奇数区间个数增1 if(i != j) swap(L->data[i],L->data[j]); } }