顺序表的相关操作 头插,尾插,头删,尾删,任意位置插入删除

顺序表的相关操作 头插,尾插,头删,尾删,任意位置插入删除

顺序表的定义

定义一个结构体来存储顺序表,结构体三个元素:数组指针data,有效元素个数size,和数组当前的容量capacity。

此处应该注意为了提高代码的适用性,我们将数组的数据类型用typedef起了个别名,slDatatype,方便后期操作其他数据类型时使用。

初始化顺序表

将顺序表初始化,即该顺序表已存在,但是内容为空

检查容量及扩容

由于该顺序表需要动态开辟空间来存储,所以在插入操作时就需要检查空间大小是否满足插入数据的需求,无论在那个位置插入元素,都需要进行检查。

尾插尾删操作

尾插:首先判断该顺序表是否合法,然后检查容量及扩容,在该数组的最后一个有效位置之后放入需要插入的数据,然后将size++,即将插入的数据存入顺序表的有效位中。

尾删:判断顺序表合法,然后直接将size- -,即最后一位不是顺序表的有效数据。此处为假删除,该位置的数据其实并未删除,只是切断了其与顺序表的联系,无法再使用。

头插头删操作

头插和头删比较尾插尾删相对复杂,因为都涉及了元素的移动。

头插:判断合法,检查容量,再将该顺序表所有元素按照从后向前的顺序,分别向后移动一位,然后在首位插入指定元素。

头删:结合头插和尾删操作,按照从前向后的顺序将元素分别向前移动一位即可。

任意位置的插入,删除

类比头插头删,尾插尾删操作,只需要在再入需要操作的位置pos即可实现,该功能实现后也可进一步优化头删头插尾删尾插操作,只要想pos分别置为0和size即可。

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<string.h>
#include<stdlib.h>

typedef int slDatatype;//顺序表内的数据类型(便于维护)

//动态顺序表
typedef struct seqList 
{
    
    
	slDatatype *data;  //数组指针
	int size;           //有效元素个数
	int capacity;       //数组内存空间

} seqList;

//初始化顺序表
void Init(seqList* sl)//形参为结构体指针
{
    
    
	sl->data = NULL;
	sl->size = 0;
	sl->capacity = 0;
}


//检查容量及扩容
void Checkcapacity(seqList*sl)
{
    
    
	if (sl->size == sl->capacity)
	{
    
    
		//开辟新空间
		int newCapacity = sl->capacity == 0 ? 1 : 2 * sizeof(sl->capacity);
		slDatatype * tmp = (slDatatype*)malloc(newCapacity*sizeof(slDatatype));

		//拷贝数据
		memcpy(tmp, sl->data, sizeof(slDatatype)*sl->size);

		//释放原有空间
		free(sl->data);
		sl->data = tmp;

	//若使用realloc动态开辟空间————可替换35-42行
		//sl->data = (seqList*)ralloc(sl->data, newCapacity * sizeof(slDatatype));

		//更新容量
		sl->capacity = newCapacity;

	}
}

//打印顺序表
void Listprint(seqList*sl)
{
    
    
	if (sl == NULL)
		return;
	for (int i = 0; i < sl->size; i++)
	{
    
    
		printf("%d ", sl->data[i]);
	}
	printf("\n");
}

//尾插
void Pushback(seqList* sl,slDatatype val)
{
    
    
	if (sl == NULL)
		return;

	Checkcapacity(sl);

	sl->data[sl->size] = val;
	sl->size++;
}

//尾删
void Popback(seqList* sl)
{
    
    
	if (sl == NULL||sl->size==0)
		return;
	if (sl->size > 0)
		sl->size--;
}


//头插
void Pushfront(seqList*sl,slDatatype val)
{
    
    
	if (sl == NULL)
		return;

	//检查容量
	Checkcapacity(sl);
    
	//移动元素--从后向前
	int end = sl->size;
	while (end > 0)
	{
    
    
		sl->data[end] = sl->data[end - 1];
		--end;
	}

	//插入元素
	sl->data[0] = val;
	sl->size++;
}


//头删
void Popfront(seqList* sl)
{
    
    
	if (sl == NULL||sl->size==0)
		return;
	
	//从前向后移动元素
	for (int i = 0; i < sl->size; i++)
	{
    
    
		sl->data[i] = sl->data[i + 1];
	}

	//更新size
	sl->size--;
}

//任意位置插入元素
void Insert(seqList*sl, int pos, slDatatype val)
{
    
    
	if (sl == NULL)
		return;
	Checkcapacity(sl);
	if (pos >= 0 && pos <= sl->size)
	{
    
    
		//移动数据
		int end = sl->size;
		while (end > pos)
		{
    
    
			sl->data[end] = sl->data[end - 1];
			end--;
		}
		//插入数据
		sl->data[pos] = val;
		sl->size++;
	}
}

//删除任意位置数据
void Erase(seqList*sl, int pos)
{
    
    
	if (sl == NULL || sl->size == 0)
		return;
	if (pos >= 0 && pos < sl->size)
	{
    
    
		while (pos<sl->size)
		{
    
    
			sl->data[pos] = sl->data[pos+1];
			pos++;
		}
		sl->size--;
	}
}

//测试模块---该部分功能根据用户需要自定义
void test()
{
    
    
	seqList sl;
	Init(&sl);
	Pushback(&sl, 1);
	Pushback(&sl, 2);
	Pushback(&sl, 3);
	Pushback(&sl, 4);

	Erase(&sl, 1);
	Listprint(&sl);


}

//销毁顺序表
void Destroy(seqList* sl)
{
    
    
	if (sl != NULL && sl->data != NULL)
	{
    
    
		free(sl->data);
		sl->data = NULL;
	}
}


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


猜你喜欢

转载自blog.csdn.net/weixin_43962381/article/details/110877108