数据结构:线性表之顺序表

实现顺序表的初始化、插入、删除、判空、判满、求值、查找、输出等操作。

之前的顺序表实现:https://blog.csdn.net/weixin_42072280/article/details/83590795

线性表是具有相同数据类型的n(n>=0)个数据元素的有限序列。

线性表是一种逻辑结构,表示元素之间一对一的相邻关系。

顺序表和链表是指存储结构,两者属于不同层面的概念。

线性表的顺序存储

用数组的连续存储空间顺序存放线性表的各元素

 

线性表的顺序存储类型描述为:

 

一维数组可以静态分配也可以动态分配

#define MaxSize  50

 

typedef struct{
    ElemType data[maxSize];    
    int length;           //表示有效元素个数 
}SqList;

#define InitSize  100

#define INCREMENT  10

 

typedef struct{
    ElemType *data;      //表示动态分配数组的指针 
    int maxSize;              //表示数组的最大容量  
    int length;                  //表示有效元素个数 
}SqList;

 

在静态分配时,由于数组的大小和空间事先已经固定,一旦空间占满,再加入新的数据将产生溢出,就会导致程序崩溃。

动态分配时,存储数据的空间是在程序执行过程中通过动态存储分配语句分配的,一旦数组空间占满,可以另外开辟一块更大的存储空间,用来替换原来的存储空间,从而达到扩充存储数组空间的目的,而不需要一次性地划分所有所需空间给线性表。

一旦因插入元素而空间不足时,可进行再分配,即为顺序表增加一个大小为存储INCREMENT个数据元素的空间。

 动态分配并不是链式 存储,同样还是属于顺序存储结构,其物理结构没有变化,依然是随机存取方式,只是分配的空间大小可以在运行时决定。

顺序表最主要的特点是随机访问,即通过首地址和元素序号可以在O{1}的时间内找到指定的元素。

顺序表的存储密度高,每个结点只存储数据元素。

顺序表逻辑上相邻的元素物理上也相邻,所以插入和删除操作需要移动大量元素。

 

方便:查找

不方便:插入 删除

 

 


#include<stdio.h>
#include<malloc.h>

#define InitSize  10
#define INCREMENT  50

#define  NOT_FOUND    -1

typedef unsigned int   boolean;
#define   TRUE     1
#define   FALSE    0 

typedef int ElemType;

typedef struct{
	ElemType *data;  //表示动态分配数组的指针 
	int maxSize;     //表示数组的最大容量 
	int length;      //表示有效数据元素个数 
}SqList;



void initList(SqList *l);      //初始化顺序表 
void destroyList(SqList *l);   //销毁顺序表

boolean  insertElement1(SqList *l, int k, ElemType x);     //在第k个位置插入元素x
boolean  insertElement2(SqList *l, int index, ElemType x); //在下标为index的位置插入元素x 

void inputData(SqList *l, int count);  //向顺序表中输入元素 
void printData(SqList *l);             //输出顺序表中的元素 

boolean deleteElement1(SqList *l, int k);     //删除顺序表中的第k个元素
boolean deleteElement2(SqList *l, int index); //删除下标为index的元素 

boolean isFull1(SqList *l);  //此处只是判断空或满,所以不需要用指针,即不用指针也可以 
boolean isEmpty1(SqList *l);

boolean isFull2(SqList l);  //此处只是判断空或满,所以不需要用指针,即不用指针也可以 
boolean isEmpty2(SqList l);


int searchElement1(SqList l, int x);  //返回该元素的下标 
int searchElement2(SqList l, int x);  //返回该元素的下标 
ElemType searchElement3(SqList l, int k);  //找第k个位置的元素 




ElemType searchElement3(SqList l, int k){
	if(k < 1 || k > l.length){
		printf("您输入的位置有误!");
		return; 
	}
	
	return l.data[k-1];
} 
 

int searchElement2(SqList l, int x){  
	int i;
	
	//printf("l.length=%d, x=%d\n", l.length, x);  // for debug 
	//for(i = 0; i < l.length || l.data[i] != x; i++){
	for(i = 0; i < l.length && l.data[i] != x; i++){  //没找完 没找到 
		;
	} 
	
	if(i < l.length){
		return i;
	}
	return NOT_FOUND;
}


int searchElement1(SqList l, int x){
	int i;
	
	for(i = 0; i < l.length; i++){
		if(l.data[i] == x){
			return i;
		} 
	}
	
	return NOT_FOUND;
}


boolean isEmpty2(SqList l){
	return l.length == 0;
}

boolean isFull2(SqList l){
	return l.length == l.maxSize;
}


boolean isEmpty1(SqList *l){
	return l->length == 0;
}

boolean isFull1(SqList *l){
	return l->length == l->maxSize;
}

boolean deleteElement2(SqList *l, int index){
	int i;
	
	if(index < 0 || index >= l->length){
		printf("您输入的下标有误,删除失败!\n");
		return FALSE;		
	} 
	
	if(l->length == 0){
		printf("线性表为空,无法进行删除 !\n");
		return FALSE;
	}
	
	for(i = index+1; i < l->length; i++){  
		l->data[i-1] = l->data[i];
	}
	l->length--;    
	
	printf("删除成功!");
	return TRUE;

} 

boolean deleteElement1(SqList *l, int k){
	int i;
	 
	if(k < 1 || k > l->length){  
		printf("您输入的位置有误,删除失败!\n");	
		return FALSE;	
	} 
	
	if(l->length == 0){
		printf("线性表为空,无法进行删除 !\n");
		return FALSE;
	}
	
	for(i = k; i < l->length; i++){  
		l->data[i-1] = l->data[i];
	}
	l->length--;    
	
	printf("删除成功!");
	return TRUE;
	
} 

void printData(SqList *l){
	int i;

	printf("顺序表中的元素为:");
	for(i = 0; i < l->length; i++){
		printf("%d ", l->data[i]);
	}
	printf("\n\n");
}


void inputData(SqList *l, int count){
	int i;

	l->length = count;
	printf("请输入%d个元素:", count);
	for(i = 0; i < l->length; i++){
		scanf("%d", &l->data[i]);
	}
	 
}

boolean  insertElement2(SqList *l, int index, ElemType x){
	int i;
	
	if(index < 0 || index > l->length){
		printf("您输入的下标有误,插入失败!\n");
		return FALSE;		
	} 
	
	if(l->length == l->maxSize){
		printf("线性表已满,无法进行插入 !\n");
		return FALSE;
	}
	
	for(i = l->length; i > index; i--){
		l->data[i] = l->data[i-1];
	}
	l->data[index] = x;
	l->length++;    

	printf("插入成功!");
	return TRUE;	
} 
 

boolean  insertElement1(SqList *l, int k, ElemType x){
	int i;
	
	//若k=length,说明在有效元素后面追加一个元素 
	if(k < 1 || k > l->length+1){  
		printf("您输入的位置有误,插入失败!\n");	
		return FALSE;	
	} 
	
	if(l->length == l->maxSize){
		printf("线性表已满,无法进行插入 !\n");
		return FALSE;
	}
	
	for(i = l->length; i >= k; i--){  
		l->data[i] = l->data[i-1];
	}
	l->data[k-1] = x;
	l->length++;    
	
	printf("插入成功!");
	return TRUE;
} 
 

void destroyList(SqList *l){
	free(l->data);
}

void initList(SqList *l){
	l->length = 0;
	l->maxSize = InitSize;
	l->data = (ElemType *)malloc(sizeof(ElemType) * l->maxSize);
}

void main(void){
	SqList list;
	int count;
	
	initList(&list);
	printf("请输入元素个数:");
	scanf("%d", &count); 
	inputData(&list, count);
	printData(&list);

/*	//插入 
	insertElement1(&list, 7, 7);
	printData(&list);
	
	insertElement2(&list, 2, 8);
	printData(&list);
*/

/*
	//删除 
	deleteElement1(&list, 0);  //删除哪个位置的 
	printData(&list);
	
	deleteElement2(&list, 0);  //删除哪个下标的 
	printData(&list);
*/

/*
	//空满 
	isFull1(&list) == 1 ? printf("该线性表是满的\n") : printf("该线性表不是满的\n");
	isEmpty1(&list) == 1 ? printf("该线性表是空的\n") : printf("该线性表不是空的\n"); 

	isFull2(list) == 1 ? printf("该线性表是满的\n") : printf("该线性表不是满的\n");
	isEmpty2(list) == 1 ? printf("该线性表是空的\n") : printf("该线性表不是空的\n"); 
*/

	//查找 
	printf("元素%d的下标是:%d\n", 5, searchElement1(list, 5));
	printf("元素%d的下标是:%d\n", list.data[3], searchElement2(list, list.data[3])); 
	printf("第%d个位置的元素是:%d\n", 2, searchElement3(list, 2)); 
	
	destroyList(&list);
} 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

安安csdn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值