线性表:顺序表(静态分配、动态分配)

顺序表:线性表的顺序存储实现。

静态分配方式

静态分配一个数组,由于没有使用动态分配内存的方式(malloc),所以并没有DestroyList(&L)函数,在程序结束后会自动销毁该数组。重要的操作有:

  • InitList(&L) :初始化顺序表。
  • ListInsert(&L,i,e):在L的位序i处插入元素e。
  • ListDelete(&L,i,&e):删除L位序i处的元素,并赋给e。
  • GetElem(L,i):按位查找,返回元素值。
  • LocateElem(L,e):按值查找,找到第一个与e相等的元素,并返回其位序。
// 线性表(linear list)的顺序存储方式--顺序表
// 顺序表的静态分配方式
//ElemType:int 
#include
#define MaxSize 10 //定义顺序表最大长度 
typedef struct{
	int data[MaxSize];//静态数组存放数据元素 
	int length;//顺序表的当前长度 
}SqList;

void InitList(SqList &L){//初始化一个顺序表 
	for(int i=0;iL.length+1){//判断i的范围是否有效 
		return false;
	}
	if(L.length>=MaxSize){//存储空间已满,不能插入 
		return false;
	}
	for(int j=L.length;j>i-1;j--){//将第i个元素及以后的元素后移 
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
}
bool ListDelete(SqList &L,int i,int &e){//删除L的位序为i的元素,将被删除的元素赋给e 
	if(i<1||i>L.length){
		return false;
	}
	e=L.data[i-1];//将被删除的元素赋给e
	for(int j=i-1;jL.length){
		printf("查找位序不合法!");
		return -1;
	}
	return L.data[i-1];
}
int LocateElem(SqList L,int e){//按值查找,找到L中第一个等于e的元素,并返回其位序 
	for(int i=0;i

动态分配

动态分配的方式数据元素在内存中依然是连续的,顺序的,只不过是长度是动态的。重要的操作有:

  • InitList(&L) :初始化顺序表。
  • IncreaseSize(&L):延长顺序表。
  • ListInsert(&L,i,e):在L的位序i处插入元素e。
  • ListDelete(&L,i,&e):删除L位序i处的元素,并赋给e。
  • GetElem(L,i):按位查找,返回元素值。
  • LocateElem(L,e):按值查找,找到第一个与e相等的元素,并返回其位序。

延长顺序表可以用malloc重新开辟一块内存,将数据复制过去,也可使用realloc尝试重新调整之前调用malloc所分配的内存块的大小:void *realloc(void *ptr, size_t size);但是可能realloc有时候会出问题?我猜是在原来内存块上延长可能会“撞”到其他的已用的内存块,导致发生错误。所以用malloc较为保险。

(int*)realloc(L.data,L.MaxSize+len);

同时要注意动态分配方式是有销毁顺序表的操作的,另外,函数中的指针free(p)释放p所指向的内存,没有写p=NULL,因为是在函数里的,函数结束后会回收;而在销毁方法里的销毁数据结构时,在free(L.data)后是要L.data=NULL置空的,手动销毁。

// 线性表(linear list)的顺序存储方式--顺序表
// 顺序表的静态分配方式
//ElemType:int 
#include
#include
#define InitSize 10 //表长度的初始定义
typedef struct{
	int* data;//指示动态分配数组的指针 
	int MaxSize,length;//数组的最大容量和当前长度 
}SeqList;

void InitList(SeqList &L){
	L.data=(int*)malloc(InitSize*sizeof(int));
	L.length=0;
	L.MaxSize=InitSize;
}
void IncreaseSize(SeqList &L,int len){//增加动态数组长度len
    //(int*)realloc(L.data,L.MaxSize+len); 
	int* p=L.data;
	L.data=(int*)malloc((L.MaxSize+len)*sizeof(int));
	for(int i=0;iL.length+1){
		return false;
	}
	if(L.length>=L.MaxSize){
		return false;
	}
	for(int j=L.length;j>i-1;j--){
		L.data[j]=L.data[j-1];
	}
	L.data[i-1]=e;
	L.length++;
	return true;
}
bool ListDelete(SeqList &L,int i,int &e){//删除位序为i的元素,并将删除的元素赋给e 
	if(i<1||i>L.length){
		return false;
	}
	e=L.data[i-1];
	for(int j=i-1;jL.length){
		printf("查找位序不合法!"); 
		return -1;
	}
	return L.data[i-1];
}
int LocateElem(SeqList L,int e){//按值查找,找到L中第一个等于e的元素,并返回其位序 
	for(int i=0;i

小结

顺序表的静态分配与动态分配只不过是一个数组长度固定,一个数组长度可以动态变化的。在物理存储上都是连续的、顺序的。

动态分配方式指针L.data同样可以用数组下标取数,所以在进行一系列操作时并没有什么区别。无非需要注意的是:

【静态分配】外部define:MaxSize,结构体内:L.length。

【动态分配】外部define:InitSize,结构体内:L.length,L.MaxSize。另外动态分配会有延长数组的操作和销毁操作。

 

你可能感兴趣的:(算法/数据结构,线性表,C)