目录
前言
顺序表是线性表的顺序存储结构的实现,基本操作有顺序表的初始化、插入、删除和查询。
一、顺序表的结构
由数据部分存储部分、数组实际使用大小和空间开辟大小。
#define LIST_SIZE 20
//数据部分结构
struct Data{
int x;
double y;
};
//顺序表的结构部分
typedef struct Node{
Data* elem; //用于动态分配
// Data elem[LIST_SIZE]; //静态分配,由于固定大小不方便,故常使用上面的
int length;
int listsize;
}Sqlist;
二、顺序表的初始化
有两种分配空间的方式:静态分配固定空间和动态分配可变空间
#define LIST_SIZE 20
bool InitSqlist(Sqlist &L){
L.elem = (Data *)malloc(LIST_SIZE * sizeof(Data));
if(!L.elem) return false;
L.length = 0; //若是静态分配只需要下面的部分
L.listsize = LIST_SIZE;
return true;
}
三、基本操作
1.插入数据
//按位插入
bool InsertList(SqList &L, int i, Data e){
if( i < 1 || i > L.length+1 ) return false;
if(L.length >= L.listsize){
Data *m =(Data *)realloc(L.s,(List_Size+100)*sizeof(Data));
if(!m) return false;
L.listsize = List_Size+100;
}
Data *p = &(L.s[i-1]);
for(Data *q = &(L.s[L.length-1]); q >= p; q--) *(q+1) = *q;
*p = e;
L.length++;
return true;
}
2.删除数据
//删除数据,找到删除数据位置,从后往前覆盖
bool DeleteList(SqList &L, int i, Data &e){
if( i < 1 || i > L.length ) return false;
Data *p = &(L.s[i-1]);
e = *p;
for(Data *q = &(L.s[L.length-1]); p < q; p++)
*p = *(p+1);
L.length--;
return true;
}
3.查找数据
void ShowList(SqList &L){
if( L.length == 0 )
printf("这是空表!\n");
for(int i = 0; i < L.length; i++ ){
printf("data[%d].x = %d\n", i , L.s[i].x);
printf("data[%d].y = %lf\n", i , L.s[i].y);
}
}
四、顺序表(数组)有关的一些经典问题
1.打印问题
(1)顺时针打印矩阵
分析:由全局到局部,找出打印规律,注意边界条件
1.二点确定一个矩形,依次向内移动左上点和右下点
2.每次对确定的矩阵,打印四条边(注意是否重复打印)
(2)Z字打印二维数组
分析:
可以按照题目逐次移动x,y打印
或者确定对角线两点,不断在这对角线来回打印
2.数组元素变换问题
(1)将0所在的行列清零
分析:利用二维数组记录需要清零的位置,避免修改原二维数组的元素为0,而导致数组全部清零(保留信息)
(2)方阵旋转
分析:逐层旋转四边对应位置的元素
(3)替换空格
3.数组查找问题
(1)二维数组查找
(2)数组中重复数字
(4)找出边界为1的最大子方阵
分析:
从N阶开始,以左上点遍历二维数组
4.数组累加和问题
(1)子数组最大累加和
分析:
解法1:遍历初始起点,遍历结果点,暴力比较所有情况得到最大区间和
解法2:前缀和求和,对求和为正数,继续累加下一元素,对求和为负数,更新重新计算求和
(2)子矩阵最大累加和
总结
数组问题一般与其他问题混合在一起出现