ArrayList(线性表)C语言实现

ArrayList(线性表)

定义:
线性表是 n(n>0) 个相同类型数据元素构成的有限序列,其中n为线性表的长度。

在这里插入图片描述

只讨论单位操作,因为范围操作不过是多次单位操作而已,对于数据结构而言知道最基本的操作即可实现稍复杂的操作

除此之外有些函数方法返回的可能是元素,也可能是bool值,而把所需值传给引用参数

线性表应有的基本操作:

FunctionDescribeO
ArrayList()建立一个新的空表1
ArrayList(Array)用数组元素依次建立线性表n
getItem(idx)返回索引为idx的元素,idx为-1时返回最后一个1
getIdx(item)返回遇到的第一个与item相同的元素索引,无返回-1n
removeItem(idx)删除索引为idx的元素n
size()返回线性表的元素数量1
contains(item)判断元素item是否在线性表中n
empty()判空1
insert(idx, item)在索引idx处,插入新元素itemn
push(item)尾插item元素1
clear()清空线性表1
set(idx, item)将索引idx处元素更改为item,并返回原元素1
expand()扩容n
/**
	ArrayList(线性表的实现)
	
	函数列表:
	 
| ArrayList()       | 建立一个新的空表                               | 1    |
| ArrayList(Array)  | 用数组元素依次建立线性表                       | n    |
| getItem(idx)      | 返回索引为idx的元素,idx为-1时返回最后一个     | 1    |
| getIdx(item)      | 返回遇到的第一个与item相同的元素索引,无返回-1 | n    |
| removeItem(idx)   | 删除索引为idx的元素                            | n    |
| size()            | 返回线性表的元素数量                           | 1    |
| contains(item)    | 判断元素item是否在线性表中                     | n    |
| empty()           | 判空                                           | 1    |
| insert(idx, item) | 在索引idx处,插入新元素item                    | n    |
| push(item)        | 尾插item元素                                   | 1    |
| clear()           | 清空线性表                                     | 1    |
| set(idx, item)    | 将索引idx处元素更改为item,并返回原元素        | 1    |
| expand()          | 扩容                                           | n    |
	 
	 此处函数列表多针对于面向对象语言实现,C语言无法完全相似实现
	 固看到的方法实现可能有些不同,下面会详细解释 
	 
*/ 

#include <stdio.h> 

// 声明ArrayList结构体(类) ,以及结构体指针 list 
typedef struct {
	int* Array;	
	int _size;		// 元素数量 
	int	_capacity;	// 容量 
} _list, *list; 

// 函数声明处 
list ArrayList();
list ArrayListByAr(int*, int);
void expand(list);
int size(list);
void push(list, int);
int getItem(list, int);
int getIdx(list, int);
void removeItem(list, int);
int removeIdx(list, int);
int contains(list, int);
int insert(list, int, int);
void clear(list);
int set(list , int , int );

// 函数实现处
list ArrayList() {
	/**
		通过malloc在堆区开辟一整块array数组,然后将地址返回 
	*/
	list array_list = (list)malloc(sizeof(_list));
	array_list->_capacity = 20;	// 初始容量为20 
	array_list->Array = (int*)malloc(array_list->_capacity * sizeof(int));	//开辟空间 
	array_list->_size = 0; 		// 初始元素数量为0 
	return array_list;
}

void expand(list array_list){
	
	/**
		扩容函数的实现是重新开辟一段更大的数组空间,
		随后将原数组元素重录到新数组中,然后释放原数组空间
		最后将线性表的数组指针指向新数组 
	*/
	array_list->_capacity *= 1.5;	// 更新容量
	int* Array = (int*)malloc(array_list->_capacity * sizeof(int) );	// 开辟更大的空间 ,容量为capacity 
	
	int i;
	for(i = 0; i < array_list->_size; i++) {
		Array[i] = array_list->Array[i];
	}	// 重录 
	
	free(array_list->Array);	// 释放缓存 
	array_list->Array = Array;	// 更换指针 
 
}

list ArrayListByAr(int* arr, int size){
	
	list array_list = (list)malloc(sizeof(_list));	// 建立线性表 
	
	if(size >= 20){
		array_list->_capacity = size + 10;	// 初始容量为size + 10
		array_list->Array = (int*)malloc(array_list->_capacity * sizeof(int));	//开辟空间 
		array_list->_size = size; 		// 初始元素数量为0 
	}
	
	else{
		array_list = ArrayList();
		array_list->_size = size;
	}
	
	int i = 0;
	for(; i < size; i++) {
		array_list->Array[i] = arr[i];
	}
	
	return array_list;
}

void show(list array_list){
	
	printf("ArrayList = [");
	int i;
	for(i = 0; i < array_list->_size - 1; i++){
		printf("%d, ", array_list->Array[i]);
	}
	if(array_list->_size) printf("%d", array_list->Array[array_list->_size - 1]);
	printf("]\n");
}

int size(list array_list){
	return array_list->_size;
}

void push(list array_list, int item){
	// 检查是否空间足够, 不够则扩容
	if(array_list->_capacity == array_list->_size) expand(array_list);
	 
	array_list->Array[(array_list->_size)++] = item;
	
}

int getItem(list array_list, int idx){
	/**
		可能会存在idx不合法的情况,但有异常处理手段
		此处不做处理 ,c语言特性会返回一个物理存储上的随机数 
	*/
	
//	if(idx < 0 || idx >= array_list->_size) 异常处理;
	
	return array_list->Array[idx];
	
}

int getIdx(list array_list, int item){
	/**
		根据元素返回索引,可能会存在元素不存在情况,
		我们返回非法索引-1 
	*/ 
	
	int i = 0; for(;i < array_list->_size; i++){
		if(array_list->Array[i] == item) return i;
	}
	
	return -1;
}

void removeItem(list array_list, int item){
	/**
		删除第一个遇到的item元素 
	*/
	
	int i = 0; for(;i < array_list->_size; i++){
		if(array_list->Array[i] == item){
			int j = i + 1;for(;j < array_list->_size; j++){
				array_list->Array[j - 1] = array_list->Array[j];
			}
			array_list->_size--;
			return;
		}
	}
}

int removeIdx(list array_list, int idx){
	/**
		此处同样存在idx不合法情况,我们针对性的返回0表示错误
		1表示删除成功, 同样的,idx = -1 时我们认为是末尾元素 
	*/
	if(idx == -1) idx = array_list->_size - 1;
	if(idx < 0 || idx >= array_list->_size) return 0;
	int i = idx + 1; for(;i < array_list->_capacity; i++){
		array_list->Array[i - 1] = array_list->Array[i];
	}
	array_list->_size --;
	return 1;
	
}

int contains(list array_list, int item){
	/**
		判断item存不存在,存在返回1, 否则返回0 
	*/
	int i = 0; for(;i < array_list->_size; i++){
		if(array_list->Array[i] == item) return 1; 
	}
	return 0;
}

int insert(list array_list, int idx, int item){
	/**
		将元素item插入索引item处,我们需要将idx之后的所有元素后移 ,
		若idx为-1,表示在末尾之前插入 , 插入成功则返回1, 否则返回0 
	*/
	
	if(idx < -1 || idx > array_list->_size) return 0;
	if(idx == -1) {
		idx = array_list->_size - 1;
	}
	
	int i = array_list->_size; for(;i > idx; i--){
		array_list->Array[i] = array_list->Array[i - 1];
	}
	array_list->Array[idx] = item;
	array_list->_size ++;
	return 1;
}

void clear(list array_list){
	/**
		为了节省时间,我们可以直接将_size赋0 
	*/	
	array_list->_size = 0;
}

int set(list array_list, int idx, int item){
	/**
		将索引为idx处的元素替换为 item, 并返回原元素 
		同样存在索引越界问题,由于c语言的性质,此处仍不考虑
		下标为-1时表示替换最后的元素 
	*/		
	if(idx == -1) idx = array_list->_size - 1;
	int oldItem = array_list->Array[idx];
	array_list->Array[idx] = item;
	return oldItem;
}

int main(){
	
	list array_list = ArrayList(); 
	
//	int a[21] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21};
//	list array_list = ArrayListByAr(a, 21);
	
	int i = 21; for(;i <= 50; i++) push(array_list, i);

	show(array_list);

//	printf("获取值:%d", getItem(array_list, 3));

//	printf("获取索引:%d", getIdx(array_list, 23));

//	removeItem(array_list, 40);

//	removeIdx(array_list, 1);

//	int num = 51;
//	if(contains(array_list, num)) printf("%d 存在\n", num);
//	else printf("%d 不存在\n", num);
	
//	int num = 99;
//	if(insert(array_list, 0, num)) printf("%d 插入成功!\n", num);
//	else printf("%d 插入失败!\n", num); 
	
//	if(insert(array_list, -1, num)) printf("%d 插入成功!\n", num);
//	else printf("%d 插入失败!\n", num); 
	
//	if(insert(array_list, 99, num)) printf("%d 插入成功!\n", num);
//	else printf("%d 插入失败!\n", num); 
	
//	clear(array_list);

//	int oldItem = set(array_list, 0, 100);
	
//	int oldItem = set(array_list, 1, 100);
	
//	int oldItem = set(array_list, -1, 100);

//	printf("%d 已被替换\n", oldItem);
	
	show(array_list);
	
	return 0;
}

// 	printf("passed!\n");
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值