2.2线性表的顺序表示

2.2.1.0 顺序表的定义

知识总览

顺序表的定义

顺序表――用顺序存储的方式实现线性表顺序存储。把逻辑上相邻的元素存储在物理位置上也相邻的存储单元中,元素之间的关系由存储单元的邻接关系来体现。

顺序表的实现——静态分配

静态顺序表
#include<stdio.h>
#define MaxSize 10
typedef struct{
	int data[MaxSize];
	int length;
}SqList; 
void InitList(SqList &L){
	L.length=0; //顺序表初始长度为0 
}
int main(){
  SqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
  for(int i=0;i<MaxSize;i++)
     printf("data[%d]=%d\n",i,L.data[i]);
  return 0;
}

顺序表的实现——动态分配

动态顺序表
#include<stdio.h>
#include<stdlib.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);  //初始化顺序表 
   //插入元素 
 IncreaseSize(L,5);
  return 0;
}

顺序表的特点:

1随机访问,即可以在 O(1}时间内找到第i个元素。

2存储密度高,每个节点只存储数据元素

3拓展容量不方便(即便采用动态分配的方式实现,拓展长度的时间复杂度也比较高)

4插入、删除操作不方便,需要移动大量元素

总结

 

2.2.2.1顺序表的插入删除

知识总览

 

顺序表的基本操作————插入

顺序表的插入
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
typedef struct{
	int data[MaxSize];
	int length;
}SqList; 
void InitList(SqList &L){
	L.length=0; //顺序表初始长度为0 
}
bool ListInsert(SqList &L,int i,int e){
	if(i<1||i>L.length+1) //判断i的范围是否有效 
	   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;
}
int main(){
  SqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
   //插入jige 元素 
  if(ListInsert(L,1,3)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
  return 0;
}

 

插入操作的时间复杂度

最好情况:最好情况:新元素插入到表尾,不需要移动元素,i= n+1;循环o次;最好时间复杂度=o(1);

最坏情况:新元素插入到表头,需要将原有的n个元素全都向后移动,i = 1,循环n次;最坏时间复杂度= O(n);

平均情况:假设新元素插入到任何一个位置的概率相同,即 i=1,2,3,... , length+1的概率都是 ,i=1,循环n次; i=2时,循环n-1次; i=3,循环n-2次....... i =n+1时,循环0次,平均循环次数=平均时间复杂度= O(n)

 

顺序表的基本操作——删除

顺序表的删除
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
typedef struct{
	int data[MaxSize];
	int length;
}SqList; 
void InitList(SqList &L){
	L.length=0; //顺序表初始长度为0 
}
bool ListInsert(SqList &L,int i,int e){
	if(i<1||i>L.length+1) //判断i的范围是否有效 
	   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;
}
bool ListDelete(SqList &L,int i, int &e){
	if(i<1||i>L.length) //判断i的范围是否有效 
	  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;
} 
int main(){
  SqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
  if(ListInsert(L,1,3)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
  int e=-1;
  if(ListDelete(L,1,e))
      printf("已删除第1个元素,删除的元素值为%d\n",e);
  else
      printf("位序i不合法,删除失败\n"); 
  return 0;
}

 

删除操作的时间复杂度

最好情况:删除表尾元素,不需要移动元素,i= n+1;循环o次;最好时间复杂度=o(1);

最坏情况:删除表头元素,需要将后续的n-1个元素全都向前移动,i = 1,循环n次;最坏时间复杂度= O(n);

平均情况:假设删除任何一个元素的概率相同,即 i=1,2,3,... , length+1的概率都是 ,i=1,循环n次; i=2时,循环n-1次; i=3,循环n-2次....... i =n+1时,循环0次,平均循环次数=平均时间复杂度= O(n)

 

总结

2.2.2.2 顺序表的查找

知识总览

 

顺序表的按位查找

按位查找(静态分配)
#include<stdio.h>
#include<stdlib.h>
#define MaxSize 10
typedef struct{
	int data[MaxSize];
	int length;
}SqList; 
void InitList(SqList &L){
	L.length=0; //顺序表初始长度为0 
}
bool ListInsert(SqList &L,int i,int e){
	if(i<1||i>L.length+1) //判断i的范围是否有效 
	   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;
}

int GetElem(SqList L,int i){
	return L.data[i-1];
}
int main(){
  SqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
  if(ListInsert(L,1,3)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
  	printf("找到了%d",GetElem(L,1));
  return 0;
}
按位查找(动态分配)
#include<stdio.h>
#include<stdlib.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);
}
bool ListInsert(SeqList &L,int i,int e){
	if(i<1||i>L.length+1) //判断i的范围是否有效 
	   return false;
	if(L.length>=L.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;
}
int GetElem(SeqList L,int i){
	return L.data[i-1];
} 
int main(){
  SeqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
  
  if(ListInsert(L,1,3)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
 IncreaseSize(L,1);
 printf("找到了%d",GetElem(L,1));
  return 0;
}

按位查找的时间复杂度

时间复杂度:O(1)

 

顺序表的按值查找

按值查找(返回位序)
#include<stdio.h>
#include<stdlib.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);
}
bool ListInsert(SeqList &L,int i,int e){
	if(i<1||i>L.length+1) //判断i的范围是否有效 
	   return false;
	if(L.length>=L.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;
}
//在顺序表L中查找第一个元素值等于e的元素,并返回其位序 
int LocateElem(SeqList L,int e){
	for(int i=0;i<L.length;i++)
	   if(L.data[i]==e)
	       return i+1;
	return 0;
} 
int main(){
  SeqList L;  //声明一个顺序表 
  InitList(L);  //初始化顺序表 
  
  if(ListInsert(L,1,3)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
  if(ListInsert(L,2,8)==false){
  	printf("插入失败,插入范围无效或存储空间已满"); 
  }
 IncreaseSize(L,1);
 printf("位序是%d",LocateElem(L,8));
  return 0;
}

结构类型的比较

不能直接用==, 而是结构体内各元素逐个比较

按值查找的时间复杂度

总结

 

posted on 2023-10-16 20:11  hellowworld!  阅读(285)  评论(0编辑  收藏  举报

导航