什么是线性表
- 线性表是一种逻辑结构
- 线性表是具有相同数据类型的n个(n>0)元素数据的有限数列
- 线性表的逻辑特性:除第一个元素外,每个元素有且只有一个直接前驱。除最后一个元素外,每个元素有且仅有一个直接后继
线性表的基础操作
- InitList(&L) 初始化表
- DestoryList(&L) 销毁表
- ListInsert(&L,i,e) 插入操作 在下标为i的位置插入值为e的元素
- ListDelete(&L,i,&e) 删除操作 删除下标为i的元素,并将其赋值给e
- LocateElem(L,e) 按值查找
- GetElem(L,i) 按位查找
线性表的实现
- 顺序表:用顺序存储的方式实现线性表,实质上是一种存储结构
通常用高级语言的数组来描述线性表的顺序存储结构,有两种方式实现
-
静态分配(数组大小和空间事先已固定,不易拓展)
#include <stdio.h> #define MaxSize 10 typedef struct{ int data[MaxSize]; int length; }SqList; void InitList(SqList &L){ for(int i = 0; i<MaxSize; i++) L.data[i] = 0; L.length = 0; } int main(){ SqList L; InitList(L); //尝试“违规”打印整个data数组 for(int i = 0; i<MaxSize; i++){ printf("data[%d] = %d\n", i, L.data[i]); } return 0; }
-
动态分配(时间开销大,主要由malloc函数和free函数实现)
//动态分配示例 #include<stdlib.h> //malloc、free函数的头文件 #include<stdio.h> #define InitSize 10 typedef struct{ int *data; int MaxSize; int 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){ int *p = L.data; L.data = (int *)malloc((L.MaxSize+len)*sizeof(int)); for(int i = 0; i<L.length; i++){ L.data[i] = p[i]; } L.MaxSize = L.MaxSize + len; free(p); } int main(){ SeqList L; InitList(L); //尝试“违规”打印整个data数组 printf("第一次打印\n"); for(int i = 0; i<InitSize; i++){ printf("data[%d] = %d\n", i, L.data[i]); } //往顺序表中随便插入几个元素 IncreaseSize(L, 5); printf("第二次打印\n"); for(int i = 0; i<InitSize+5; i++){ printf("data[%d] = %d\n", i, L.data[i]); } return 0; }
顺序表特点
- 随机访问
- 存储密度高
- 拓展容量不方便
- 插入和删除需要移动大量元素
顺序表基本操作
插入操作
//代码实现
#include<stdio.h>
#define MaxSize 10
typedef struct{
int data[MaxSize];
int length;
}SeqList;
bool ListInsert(SeqList &L,int i,int e){
if(i<1||i>L.length+1)
return false;
if(L.length>=MaxSize)
return false;
for(int j=L.length;j>=i;j--)
L.data[j]=L.data[j-1];
L.data[i-1]=e;
L.length++;
return true;
}
void InitList(SeqList &L){
for(int i = 0; i<MaxSize; i++)
L.data[i] = 0;
L.length = 0;
}
int main(){
SeqList L;
InitList(L);
printf("第一次打印\n");
for(int i = 0; i<6; i++){
L.data[i]=i;
L.length++;
printf("data[%d] = %d\n", i, L.data[i]);
}
ListInsert(L,3,111);
printf("第二次打印\n");
for(int i = 0; i<MaxSize; i++)
printf("data[%d] = %d\n", i, L.data[i]);
return 0;
}
删除操作
//代码实现
#include<stdio.h>
#define MaxSize 10
typedef struct{
int data[MaxSize];
int length;
}SeqList;
bool ListDelete(SeqList &L,int i,int &e){
if(i<1||i>L.length)//判断是否越界
return false;
e= L.data[i-1];//将删除元素的值赋给e
for(int j=i;j<L.length;j++)//将i及以后的元素向前移
L.data[j-1]=L.data[j];
L.length--;//表的长度减一
return true;
}
void InitList(SeqList &L){
for(int i = 0; i<MaxSize; i++)
L.data[i] = 0;
L.length = 0;
}
int main(){
SeqList L;
InitList(L);
for(int i=0;i<5;i++){
L.data[i]=i;
L.length++;
}
int i=3;
int e=-1;
if(ListDelete(L,i,e))
printf("已删除第%d个元素,删除元素的值为%d\n",i,e);
else
printf("删除失败!\n");
printf("打印整个顺序表\n");
for(int i=0;i<L.length;i++)
printf("data[%d]=%d\n",i,L.data[i]);
return 0;
}
按值查找
1.按位查找
//代码实现
#include<stdio.h>
#define MaxSize 10
typedef struct{
int data[MaxSize];
int length;
}SeqList;
void InitList(SeqList &L){
for(int i = 0; i<MaxSize; i++)
L.data[i] = 0;
L.length = 0;
}
int GetElem(SeqList L,int i){
return L.data[i-1];
}
int main(){
SeqList L;
InitList(L);
for(int i=0;i<5;i++){
L.data[i]=i;
L.length++;
}
int i=2;
for(int i = 0; i<L.length; i++)
printf("data[%d] = %d\n", i, L.data[i]);
printf("位置为%d的元素值为%d\n",i,GetElem(L,i));
return 0;
}
2.按值查找
//代码实现
#include<stdio.h>
#define MaxSize 10
typedef struct{
int data[MaxSize];
int length;
}SeqList;
void InitList(SeqList &L){
for(int i = 0; i<MaxSize; i++)
L.data[i] = 0;
L.length = 0;
}
int LocateElem(SeqList L,int e){
int i;
for(i=0;i<L.length;i++)
if(L.data[i]==e)//找到值为e的元素位置
return i+1;//下标从0开始,所以i+1
return 0;
}
int main(){
int i;
SeqList L;
InitList(L);
for(int i=0;i<5;i++){
L.data[i]=i;
L.length++;
}
int e=2;
for(int i = 0; i<L.length; i++)
printf("data[%d] = %d\n", i, L.data[i]);
printf("值为%d的元素下标为%d\n",e,LocateElem(L,e));
return 0;
}