顺序表的增、删、改、查的实现

如何编程

  1. 需求分析:明确我们要处理什么问题(要完成什么功能)。确定我们处理问题所需要的资源。
  2. 算法设计:根据所需要的功能和我们所需要的资源,理清思路,排列出完成此功能的具体步骤。每一个步骤都应该是简单的确定的
  3. 编写程序:根据前期设计好的步骤,编写复合C语言规则的程序。
  4. 检查程序,没有错误了就编译和链接程序。
  5. 检测数据,测试程序是否符合要求。

可增容顺序表的代码实现(及其增删改查操作)

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

#define INIT_SIZE 10
#define SELERROR -1

typedef int ElemType;

typedef struct SeqTable
{
	ElemType* data;
	int len;
	int val_len;
}Seq,*pSeq;

void Init_Seq(pSeq plist)
{
	plist->data = (ElemType*)malloc(sizeof(ElemType)*INIT_SIZE);
	plist->len = INIT_SIZE;
	plist->val_len = 0;
}

bool Inc_Capacity(pSeq plist)
{
	assert(plist != NULL);
	ElemType* newdata = NULL;
	int total = plist->len * 2;
	newdata = (ElemType*)malloc(sizeof(ElemType) * total);
	if (newdata == NULL)
	{
		return false;
	}
	for (int i = 0; i < plist->val_len; ++i)
	{
		newdata[i] = plist->data[i];
	}

	plist->data = newdata;
	plist->len = total;

	return true;
}
bool is_Full(pSeq plist)
{
	assert(plist != NULL);
	return plist->len == plist->val_len;
}

bool is_Empty(pSeq plist)
{
	assert(plist != NULL);
	return plist->val_len == 0;
}

bool Insert_Seq(pSeq plist,int pos,ElemType value)
{
	assert(plist != NULL);
	if (pos<0 || pos>plist->val_len)
	{
		printf("插入的位置有错!");
		return false;
	}
	if (is_Full(plist))
	{
		Inc_Capacity(plist);
	}
	for (int i = plist->val_len; i > pos; i--)
	{
		plist->data[i] = plist->data[i - 1];
	}
	plist->data[pos] = value;

	plist->val_len++;

	return true;
}

bool Push_back(pSeq plist, ElemType value)
{
	assert(plist != NULL);
	if(is_Full(plist))
	{
		Inc_Capacity(plist);
	}
	plist->data[plist->val_len] = value;
	plist->val_len++;

	return true;
}

bool Push_Front(pSeq plist, ElemType value)
{
	assert(plist != NULL);
	for (int i = plist->val_len; i >0; --i)
	{
		plist->data[i] = plist->data[i - 1];
	}
	plist->data[0] = value;
	plist->val_len++;

	return true;
}

void Del_Seq(pSeq plist, ElemType value)
{
	assert(plist != NULL);
	if (is_Empty(plist))
	{
		printf("表中无数据!");
		return;
	}
	int i = 0;
	for (; i < plist->val_len; ++i)
	{
		if (plist->data[i] == value)
		{
			break;
		}
	}

	for (; i < plist->val_len - 1; ++i)
	{
		plist->data[i] = plist->data[i + 1];
	}

	plist->val_len--;
}

void Del_pos_Seq(pSeq plist, int pos)
{
	assert(plist != NULL);
	if (is_Empty(plist))
	{
		printf("表中无数据!");
		return;
	}

	for (int i = pos; i < plist->val_len-1; ++i)
	{
		plist->data[i] = plist->data[i + 1];
	}

	plist->val_len--;
}

ElemType Pop_Front(Seq* plist)
{
	ElemType value = plist->data[0];
	Del_pos_Seq(plist, 0);

	return value;
}

ElemType Pop_Back(Seq* plist)
{
	ElemType value = plist->data[plist->val_len-1];
	plist->val_len--;

	return value;
}


//按位置改变数据,将pos位置上的数据改变
bool Revise_Seq(pSeq plist, int pos, ElemType value)
{
	assert(plist != NULL);
	if (pos<0 || pos>plist->val_len - 1||is_Empty(plist))
	{
		return false;
	}

	plist->data[pos] = value;
}


//按位置查询数据
ElemType Select_Seq(pSeq plist, int pos)
{
	assert(plist != NULL);
	if (pos<0 || pos>plist->val_len - 1 || is_Empty(plist))
	{
		return SELERROR;
	}

	return plist->data[pos];
}

void show(pSeq plist)
{
	for (int i = 0; i < plist->val_len; ++i)
	{
		printf("%d   ", plist->data[i]);
	}
	printf("\n");
}


int main()
{
	Seq p;
	Init_Seq(&p);
	for (int i = 0; i < 10; ++i)
	{
		Insert_Seq(&p, i, i * 10);
	}
	Push_back(&p, 10000);
	Push_Front(&p, 9999);
	ElemType head, tail;
	head = Pop_Front(&p);
	tail = Pop_Back(&p);

	Revise_Seq(&p, 3, 400);

	Del_pos_Seq(&p, 3);

	printf("head=%d,tail=%d\n", head, tail);

	show(&p);

	ElemType svalue=Select_Seq(&p, 3);
	printf("pos:%d的数据是%d\n", 3, svalue);
}

以下纯属个人理解,欢迎指正:

我认为顺序表其实就是数组的另一种叫法,可增容顺序表、不可增容顺序表,还有一种用一个数组实现的顺序表(叫什么我还忘了),其实都可以将其当成数组来处理,因为他们在内存上都是连续的,这一点和一个数组是一样的,只不过顺序表(这里只讲可增容顺序表,不可增容的和数组其实一样,就没有讨论的比必要了)可能显得更高级一点,他是通过一个结构体中的一个指针指向堆区中的一块连续空间实现的,具体操作方法还是大同小异,查询很方便,但是涉及到增删操作的时候需要一定大量的数据,造成时间复杂度很高

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值