数据结构不定长顺序表

在定长顺序表的基础上进行改动:

1、结构体设计

2、

typedef int ELEM_TYPE;
#define INIT_SIZE 10

//不定长顺序表的结构体设计:
typedef struct Dsqlist
{
	ELEM_TYPE *elem;//指针,用来接收malloc返回值
	int length;//当前有效值个数(当前有多少个格子被占用)
	int list_size;//当前总空间个数(当前一共有多少个格子)
}Dsqlist, *PDsqlist;

2、不定长顺序表的基本操作

(1)初始化

void Init_Dsqlist(struct Dsqlist * p)//void Init_sqlist(PDsqlist p);
{
	assert(p != NULL);//断言
	if(p == NULL)
		return;

	p->elem = (ELEM_TYPE*)malloc(INIT_SIZE * sizeof(ELEM_TYPE));//动态申请内存,申请的内存指针为p->elem 
	assert(p->elem != NULL);
	if(p->elem == NULL)
		return;

	p->length = 0;
	p->list_size = INIT_SIZE;
}

(2)按位置插入

//按位置插入
bool Insert_pos(PDsqlist p, int pos, int val)
{
	//assert    p
	//assert    pos 
	//判满   扩容   
	if(IsFull(p))
	{
		Inc(p); 
	}
	//此时,肯定p不为NULL, 并且pos位置合法, 并且还用空闲位置让我插入
	
	//4.首先挪动数据,让待插入位置空出来,再将值val放进去即可
	//(插入,挪动数据,从后先前挪)

	for(int i=p->length-1; i>=pos; i--)//i一开始指向最后一个元素下标,最后挪动的数据下标是pos
	{
		p->elem[i+1] = p->elem[i];
	}
	//此时,for循环执行结束  标识着挪动数据完成   现在只需要将插入的值val赋值进去
	p->elem[pos] = val;
	//别忘了 插入操作最后还有一个有效值个数length++
	p->length++;

	return true;
}

(3)按位置删除

//按位置删除
bool Del_pos(PDsqlist p, int pos)
{
	//1.判空  p!=NULL    判断定长顺序表是否存在
	assert(p!=NULL);
	if(p == NULL)
		return false;

	//2.判断删除位置 是否合法
	assert(pos >=0 && pos<p->length);//  删除的时候pos==p->length不合法
	if(pos<0 || pos>=p->length)
		return false;

	//3.判空操作
	if(IsEmpty(p))
		return false;


	//4.将待删除位置后面的有效值,一次向前挪动一位,将删除位置覆盖掉即可
	//(删除,向前覆盖数据,离待删除位置最近的元素先挪动)

	for(int i=pos+1; i<=p->length-1; i++)
	{
		p->elem[i-1] = p->elem[i];
	}
	//此时,for循环执行结束  标识着数据向前覆盖完成   现在只需要将p->length--
	p->length--;

	return true;


}

(4)按值删除

//按值删除
bool Del_val(PDsqlist p, int val)
{
	//assert p
	//判断val这个值  存不存在
	int index = Search(p, val);
	if(index == -1)
	{
		return false;
	}

	return Del_pos(p, index);
}

(5)获取有效长度、获取值所在的下标

//获取其有效长度
int Get_length(PDsqlist p)
{
	//assert
	return p->length;
}

//获取值所在下标(如果数据重复,则返回val第一次出现的位置)
int Search(PDsqlist p, int val)
{
	//assert
	for(int i=0; i<p->length; i++)
	{
		if(p->elem[i] == val)
		{
			return i;
		}
	}
	return -1;
}

(6)以2倍扩容

//扩容    以2倍扩容  
void Inc(PDsqlist p)
{
	//assert  p   这个断言需不需要?  不需要
	p->elem = (ELEM_TYPE*)realloc(p->elem, p->list_size*sizeof(ELEM_TYPE) * 2);
	assert(p->elem != NULL);
	if(p->elem == NULL)
	{
		printf("realloc error\n");
		return;
	}
		

	//p->length;//扩容之后 有效值个数不变
	p->list_size *= 2;//扩容之后  总格子个数需要*2

}

(7)判空、判满、清空、销毁、打印

//判空
bool IsEmpty(PDsqlist p)
{
	//assert
	return p->length == 0;
}
//判满
bool IsFull(PDsqlist p)
{
	//assert
	return p->length == p->list_size;
}

//清空
void Clear(PDsqlist p)
{
	//assert
	p->length = 0;
}

//销毁  主要处理内存泄露
void Destroy(PDsqlist p)
{
	//assert
	free(p->elem);
}

//打印
void Show(PDsqlist p)
{
	//assert
	for(int i=0; i<p->length; i++)
	{
		printf("%d ", p->elem[i]);
	}
	printf("\n");
}

3、主函数调用测试

//不定长顺序表测试用例
int main()
{
	struct Dsqlist head;
	Init_Dsqlist(&head);
	printf("maxsize: %d\n", head.list_size);
	printf("length = %d\n", Get_length(&head));

	
	for(int i=0; i<10; i++)
	{
		Insert_pos(&head, i, i+1);
	}
	Insert_pos(&head, 0, 100);
	Insert_pos(&head, head.length, 200);
	printf("maxsize: %d\n", head.list_size);
	printf("length = %d\n", Get_length(&head));
	Show(&head);


	Del_pos(&head, 3);
	Show(&head);
	Del_val(&head, 9);
	Show(&head);

	printf("%d\n", Search(&head, 5));
	printf("%d\n", Search(&head, 300));

	Clear(&head);
	printf("length = %d\n", Get_length(&head));
	Show(&head);

	Destroy(&head);

	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值