2.0 线性表的定义与基本运算
线性结构 基本特点: 在* 同构 的N个数据元素的 非有限集 *中
- 存在唯一的一个被称作为“第一个” 的数据元素
- 存在唯一的一个被称作为“最后一个” 的数据元素
- 除第一个外,集合中的每个数据元素均只有一个直接前驱
- 除最后一个外,集合中的每个数据元素均只有一个直接后继
故此,有线性表如下的定义 : (a 1 ,a 2 ,a 3 ,?,a n )
一个线性表是 n 个同构的数据元素的有限序列.
其特征如下:
- 元素是同构的,且不能出现缺项 (即:每对相邻的两元素之间的步长均是1)
- 记元素个数 n 作表的长度.
- 当 n = 0时,记作 空表
- 当 n > i > 1 时,
- a i 的直接前驱是a i?1 ;其直接后继是a n+1
- 若表不是循环表,则 a 1 无前驱,a n 无后继
2.1 线性表的逻辑结构
数据元素又称为 结点,其种类有:
- 单值型元素 每个元素只有一个数据项(item)
- 记录型元素 每个元素含有多个数据项.
- 此时称每个数据项为结点的一个域
- 其中唯一标识一个结点的域的组合(一个或多个域) 被称为关键字
2.2 线性表的存储结构
2.2.1 顺序表(线性表的顺序存储结构)
顺序表 :把线性表的结点按逻辑结构依次存放在一组地址连续的存储单元里.
顺序表的特点:
- 线性表的逻辑顺序与物理顺序一致
- 数据元素之间的关系是以元素在计算机内‘物理位置相邻’来体现
相应的有如下类似的存储位置的关系表达式
LOC(a i )=LOC(a i?1 )+L
LOC(a n )=LOC(a i )+(n?i)?L
其中 L 为 每个元素占用的存储单元
2.2.2 顺序表的基本操作与实现
基本操作:
- 创建
- 赋值
- 查找
- 修改
- 插入
- 删除
- 求长度
顺序表的C++实现
#include <stdio.h> // for printf
#include <stdlib.h> // for calloc,free
#include <string.h> // for memmove
#define SEQLIST_DEFAULT_SIZE 10
///说明 : T 必须支持[]操作的复合类型,或者是基本类型
template<typename T>
struct SeqList {
public:
SeqList(int size=SEQLIST_DEFAULT_SIZE) {
init(size);
}
bool delete(int idxDelete,T* saveOut=NULL){
//顺序表不为空,并且 idxDelete 在合理范围内
if(curSize && idxDelete>=0&& idxDelete<=curSize) {
if(saveOut)
*saveOut=data[idxDelete];
for(int i=idxDelete;i<curSize;i++)
data[i-1]=data[i];
curSize--;
return true;
}
return false;
}
void display(){
getInfo();
for(int i=0;i<curSize;i++){
printf("%d elem is %d\n",i,data[i]);
}
}
//查找数据 s 是否在表里面
//s 不在表里面,返回-1,否则返回 s 在表里的下标
int find(T s){
for(int i=0;i<curSize;i++) {
if(data[i] == s){
return i;
}
}
return -1;
}
//打印顺序表的信息
void getInfo(){
printf("顺序表[0x%x] 容量:%d,当前大小:%d\n",data,capacity,curSize);
}
///插入
bool insert(T elemInsert,int idxInsert=-1){
//数据元素已经满员但是扩容失败了
if(curSize>=capacity-1 && 0 != enlargeSize())
return false;
if(idxInsert>0){
for(int j=curSize-1;j>=idxInsert;j--){
data[j+1]=data[j];
}
idxInsert--;
}else{
idxInsert=curSize;
}
data[idxInsert]=elemInsert;
curSize++;
return true;
}
bool isFull(){
return curSize+1>=capacity;
}
bool isEmpty(){
return curSize==0;
}
bool isValidIndex(int idx) {
if(idx < 0 || idx > curSize){
return false;
}
return true;
}
int length(){
return curSize;
}
private:
T* data;
int curSize;
int capacity;
//扩容操作
//返回0 已经成功扩容了一倍
//返回-1,扩容失败
int enlargeSize(){
capacity <<= 1;
T* nb=(T*)calloc(capacity,sizeof(T));
if(nb){
memmove(nb,data,curSize*sizeof(T));
printf("[TIP]SeqList(0x%x)已满,自动扩展当前大小一倍\n",data);
data=nb;
return 0;
}
return -1;
}
///初始化
int init(int nSize=SEQLIST_DEFAULT_SIZE){
data=(T*)calloc(nSize,sizeof(T));
if(!data){
return -1;
}
capacity=nSize;
curSize=0;
return 0;
}
};
#ifndef DYLIB
int main(){
SeqList<int> isl;
int testArr[11]={40,41,42,43,44,140,142,143,144,145,146};
for(int i=0;i<sizeof(testArr)/sizeof(testArr[0]);i++) {
isl.insert(testArr[i]);
}
isl.display();
//insert again
for(i=0;i<sizeof(testArr)/sizeof(testArr[0]);i++) {
isl.insert(testArr[i]);
}
isl.display();
return 0;
}
#endif
时间: 2024-08-09 10:43:03