线性表的顺序表示是指用一组地址连续的存储单元依次存储线性表的数据元素。既然它们的地址是连续的,也就是可以由任意已知的表中数据的地址及相对位置推出我们感兴趣的元素地址。
例线性表每个元素所占的存储单元为l个,则可得到:
LOC(A(i+1))=LOC(Ai)+l;//其中LOC()为该元素的地址。
我们所知的array和vector都是顺序表。不清楚的同学可以看看这篇blog:http://blog.csdn.net/ah_107/article/details/52729260
今天我们主要是来探讨下如何具体实现顺序表的常见的几种基本操作:
首先:创建顺序存储结构,我们一般都用array来描述。那么这个结构体必须得满足以下几点:
①有表示该现行表的基地址的成员 ②有表示该线性表的长度 ③有表示预定义大小空间的变量
根据以上几点,我们可以有如下表示:
//c语言实现(struct)
#define List_init_size 100 //线性表存储空间的初始化分配
#define Listincrement 10 //当线性表内存不足时,开辟新空间的增量
typedef struct{
int *elem;//表示当前顺序表的首地址
int length;//实际长度
int listsize;//分配的空间长度
}sqlist;
bool InitList_sq(sqlist &L)
{
L.elem = (int*)malloc(List_init_size*sizeof(int));
if (!L.elem) return 0;
L.length = 0;
L.listsize = List_init_size;
return 1;
}
int main(void)
{
sqlist L;
bool q = InitList_sq(L);
if (!q)
{
cout << "make falut when initial list" << endl;
}
cout << "length of list:"<<L.length << endl;
cout << "size of list:" << L.listsize << endl;
return 0;
}
用class实现也是一模一样,只不过在结构体中成员默认是public的,而class默认是私有的,故用class编写的时候就要显示地把成员变量声明成public。
上述操作就可以创建一个顺序表,并初始化。
之前的博文说到顺序表由于地址是连续的,所以在表中实现插入或者删除的时候就有可能出现大批量的数据移动。
现在我们来具体实现顺序链表的元素添加:
bool add_sq(sqlist &L,int e)
{
*(L.elem) = e;
L.length++;
return 1;
}
现在我们来具体实现顺序链表的元素插入:
bool insert_sq(sqlist &L, int i, int e)
{
if (L.length+1 > i||i<1)
{
cout << "out of range!" << endl;
return 0;
}
if (L.length > L.listsize)//当顺序表长度大于所分配的空间,则从新分配更大的空间
{
int* newbase = (int*)realloc(L.elem, (L.listsize + Listincrement)*sizeof(int));
if (!newbase) { cout << "unsucess!"; return 0; }
L.elem = newbase;
L.listsize = L.listsize + Listincrement;
}
auto q = &(L.elem[i - 1]);//获取插入点位置
for (auto p = &(L.elem[L.length - 1]); p >= q; --p)
*(p + 1) = *p;//插入点以后全部后移一位
*q = e;
++L.length;//表长加一
return 1;
}