数据结构与算法——顺序表的实现

结构体

struct List {
	int *arr;
	int capacity;
	int size;
};

结构体中有三个元素。第一个是用于存储的顺序表元素的数组,顺序表的特点是物理位置相邻的元素逻辑位置也相邻。第二个是数组的容量,这个在初始化时需要分配空间,并且在插入操作时注意数组是否已经填满,防止出现数组越界。第三个是顺序表中元素的个数。

初始化链表

int InitList(struct List *list){
	list->arr=malloc(sizeof(struct List)*8);    //分配空间
	if (list->arr==NULL) return 0;      //判断空间是否分配成功,如果分配失败,返回0
	list->capacity=8;                   //数组容量
	list->size=0;                       //顺序表元素个数
	return 1;
}

malloc()函数是用于分配空间的函数,sizeof()函数用来返回数据类型的大小,整个的作用是分配一个可以存储8个int整型变量的空间,数组指针指向这片空间。将数组容量和顺序表元素个数初始化。这里函数的返回值定义为布尔或者整形都可以,意为初始化成功与否,0为失败,1为成功。

插入操作

int InsertList(struct List *list,int element,int index){
	if(index<1||index>list->size+1) return -1;       //判断插入位置的合法性 
	if (list->size==list->capacity){                 //判读数组容量是否已满
		int newcapacity=list->capacity*2;
		int *newarr=realloc(list->arr,sizeof(struct List)*newcapacity);
		if (newarr==NULL) return 0;                  //判断空间是否分配成功
		list->arr=newarr;
		list->capacity=newcapacity;
	}
	int i=0;
	for(i=list->size;i>index-1;i--){
		list->arr[i]=list->arr[i-1];                 //将插入位置之后的元素都向后移一位
	}
	list->arr[index-1]=element;                      //后移腾出的位置插入元素
	list->size++;
	return 1;
}

插入操作第一个参数为需要操作的顺序表,第二个参数为需要插入元素的位序。注意,位序是从1开始,而数组下标是从0开始。在插入操作中,要注意在顺序存储结构中,数组的容量是有限的,在数组已满的时候,需要有扩容操作,才能继续插入。在扩容时,realloc()函数会按参数分配空间大小,并将原来的数组空间中的元素拷贝到新空间中,以此完成数组的扩容操作。顺序存储结构在插入时,需要腾出所指定的位置,所以需要将插入位置和之后的元素都想后移。此处要注意,要从顺序表最后的元素开始,如果从插入位置n开始移,即list->arr[n]=list->arr[n+1],这种操作会将n+1位置处的元素覆盖,所以需要从后开始移,最后完成时将顺序表的长度+1。插入函数返回值同初始化。

删除操作

int DeleteList(struct List *list,int index){
	if (index<1||index>list->size) {
		return 0;	
	}
	int i=0;
	for (i=index;i<list->size;i++){
		list->arr[i-1]=list->arr[i];
	}
	list->size--;
	return 1;
}

删除操作第一个参数为需要操作的顺序表,第二个参数为需要删除元素的位序。首先和插入如操作相同,需要判断插入位置的合法性。而删除操作是需要将删除位置覆盖,所以可以直接从删除位置n的后一位n+1依次开始向前挪。最后别忘了顺序表长度需要修改。

查找元素

int FindList(struct List *list,int element){
	int i=0;
	for (i=0;i<list->size;i++){
		if (element==list->arr[i]) return i+1;
	}
	return -1;
}

这里是查找指定值是否存在顺序表中,如果存在,则返回元素位序,如果不存在,就返回-1。通过循环遍历顺序表,判断每一个元素是否和参数相等。这里注意位序=数组下标+1。

获取元素

int GetList(struct List *list,int index){
	if (index<1||index>list->size) return -1;
	return list->arr[index-1];
}

这个操作的作用是返回顺序表指定位置的元素。注意位序的合法性以及位序和下标的不一致性。

获取长度

int Listsize(struct List *list){
	return list->size;
}

这个函数是为了返回顺序表的长度,很简单的函数。

遍历打印

void PrintList(struct List *list){
	int i=0;
	for (i=0;i<list->size;i++){
		printf("%d ",list->arr[i]);
	}
	printf("\n");
}

每次操作完顺序表后,为了方便查看顺序表情况,编写一个遍历顺序表并将顺序表元素打印在控制台上的函数。有一个注意的小地方是,循环体中的语句printf("%d ",list->arr[i]);,%d后面加一个空格,即每一个元素直接会有空格分隔。在最后全部打印结束后换行,用于分隔下一次打印的内容。

完整代码

#include <stdio.h>
#include <stdlib.h>

struct List {
	int *arr;
	int capacity;
	int size;
};

int InitList(struct List *list){
	list->arr=malloc(sizeof(int)*8);
	if (list->arr==NULL) return 0;
	list->capacity=8;
	list->size=0;
	return 1;
}

void PrintList(struct List *list){
	int i=0;
	for (i=0;i<list->size;i++){
		printf("%d ",list->arr[i]);
	}
	printf("\n");
}

int InsertList(struct List *list,int element,int index){
	if(index<1||index>list->size+1) return -1;       //判断插入位置的合法性 
	if (list->size==list->capacity){
		int newcapacity=list->capacity*2;
		int *newarr=realloc(list->arr,sizeof(int)*newcapacity);
		if (newarr==NULL) return 0;
		list->arr=newarr;
		list->capacity=newcapacity;
	}
	int i=0;
	for(i=list->size;i>index-1;i--){
		list->arr[i]=list->arr[i-1];
	}
	list->arr[index-1]=element;
	list->size++;
	return 1;
}

int DeleteList(struct List *list,int index){
	if (index<1||index>list->size) {
		return 0;	
	}
	int i=0;
	for (i=index;i<list->size;i++){
		list->arr[i-1]=list->arr[i];
	}
	list->size--;
	return 1;
}

int FindList(struct List *list,int element){
	int i=0;
	for (i=0;i<list->size;i++){
		if (element==list->arr[i]) return i+1;
	}
	return -1;
}

int GetList(struct List *list,int index){
	if (index<1||index>list->size) return -1;
	return list->arr[index-1];
}

int Listsize(struct List *list){
	return list->size;
}

int main(){
	...
	return 0;
}


评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值