我作为一个编程界的 渣渣,痛定思痛,决定从头开始巩固基础知识。数据结构则首当其冲是任何程序能够变得优美的基础。以下概念如果有不够严谨和准确的地方,欢迎提出一起讨论。
- **顺序线性表**
顾名思义是以顺序存储为结构的线性表,是最基础的线性表,这里的顺序不仅是指逻辑地址的连续性,也表示物理地址的连续性。因此,顺序线性表是存储在一段连续地址空间的数据的集合。
这样的存储特性带来了易于查找和定位表中数据的优点, 但同时,插入或删除信息的过程比较低效,尤其当数据量很大时,大大增加了时间成本。
----------
这里采用C++对主要模块功能进行了实现,首先定义基础结构,初始化,插入数据,删除数据,查找数据;查找前驱、后驱,清空线性表,销毁线性表,查看线性表等。通过对插入删除初始化这三个主要功能的研究,对如何用指针、引用、函数调用、动态分配内存的过程实现理解深刻后, 其他功能的实现自然也能举一反三。
#define INIT_SIZE 5
#define LISTINCREMENT 1
typedef int Elemtype;
/*定义基础结构*/
typedef struct
{
Elemtype *elem;
int length; //实际使用的线性表容量
int listsize; //初始开辟的线性表总长度
}sql;
/*初始化线性表*/
int Initlist(sql &L)
{
L.elem = (Elemtype*)malloc(sizeof(Elemtype)*INIT_SIZE)
if(L.elem==NULL) return OVERFLOW;
L.length = 0;
L.listsize = INIT_SIZE;
retuen OK;
}
/*线性表中插入元素
可能出现的情况:
1. i的位置超出线性表长度的左右范围;
2. 插入i后线性表长度超出总容量;
3. 线性表长度为0,直接插值;
4. 线性表长度不为0,依次向后移动i位序之后的值,再插入。*/
int Listinsert(sql &L, int i, Elemtype value) //在线性表第i个元素前插入value
{
Elemtype *newsize, *p, *q;
if(i<1||i>L.length+1) return ERROR;
if(L.length>=L.listsize)
{
newsize = (Elemtype*)realloc(L.elem, sizeof(Elemtype)*(L.listsize+LISTINCREMENT));
if(newbase ==NULL) return OVERFLOW;
L.elem = newsize;
L.listsize += LISTINCREMENT;
}
q = &(L.elem[i-1]); //q取第i个元素的地址
if(L.length==0)
{
*q = value;
L.length++;
}
else
{
for(p = &(L.elem[L.length-1]);p>=q;p--)
{
*(p+1) = *p;
}
*q = value;
L.length++;
}
return OK;
}
/*删除线性表第i个元素,返回被删除的值value*/
int Listdelete(sql &L, int i, Elemtype &value)
{
Elemtype *p;
value = L.elem[i-1];
if(i<1||i>L.length) return ERROR;
for(p = &(L.elem[i]);p<=&(L.elem[L.length-1]);p++)
{
*(p-1)=*p;
}
L.length--;
return OK;
}