DS开篇之作——手撕顺序表


DS开篇之作——手撕顺序表

  • 前言
  • 一、顺序表是什么
  • 二、顺序表的功能
    • 煎炒烹炸,焖溜熬炖,增删查改
  • 三.顺序表的实现
    • 基础操作
      • 1.初始化
      • 2.扩容
      • 3.顺序尾插
      • 4.顺序头插
      • 5.顺序尾删
      • 6.顺序头删
      • 7.查找
      • 8.修改
    • 优化
      • 1.插入操作优化
      • 2.删除操作优化
  • 四.测试用例
    • 数据导入
    • 头插
    • 删除第四个数据(3)
    • 4和5间插入数据100
    • 查找100的位置
    • 把数据4修改成-6
  • 总结:


前言

本文详解顺序表的实现,便于读者朋友们对数据结构的学习建立信心
顺序表是最简单的数据结构,可能有些读者朋友因为对C语言的基础不牢或是
学校老师从不带学生敲代码实现各种功能导致不能很好掌握,希望看完这
篇文章后可以有些收获。

一、顺序表是什么

定义:

  • L 顺序表是用一段物理地址连续的存储单元依次存储数据元素的线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
  • 顺序表:可动态增长的数组,要求数据是连续存储的

二、顺序表的功能

煎炒烹炸,焖溜熬炖,增删查改

DS开篇之作——手撕顺序表_第1张图片
四大功能,逐一实现!!!

三.顺序表的实现

基础操作

1.初始化

给一个顺序表开辟空间,size表示数据个数,capacity表示容量,a表示元素首地址
DS开篇之作——手撕顺序表_第2张图片

void SLInit(SL* psl)
{
	assert(psl);
	psl->a = (SLDatatype*)malloc(sizeof(SLDatatype) * 4);
	if (psl->a == NULL)
	{
		perror("malloc fail");
		return;
	}

	psl->capacity = 4;
	psl->size = 0;
}

2.扩容

随着数据的不断输入,空间不够,所以需要不断开辟空间满足需求,一般都是给现有的数据开辟两倍的大小
DS开篇之作——手撕顺序表_第3张图片

void SLCheckCapacity(SL* psl)
{
	assert(psl);

	if (psl->size == psl->capacity)
	{
		SLDatatype* tmp = (SLDatatype*)realloc(psl->a, sizeof(SLDatatype) * psl->capacity * 2);
		if (tmp == NULL)
		{
			perror("realloc fail");
			return;
		}

		psl->a = tmp;
		psl->capacity *= 2;
	}
}

3.顺序尾插

向顺序表的尾部插入一个数据
DS开篇之作——手撕顺序表_第4张图片

void SLPushBack(SL* psl, SLDatatype x)
{
	assert(psl);

	psl->a[psl->size] = x;
	psl->size++;

	SLCheckCapacity(psl);

	psl->a[psl->size++] = x;

	/*SLInsert(psl, psl->size, x);*/
}

4.顺序头插

向顺序表头部插入一个数据,相当于生活中的排队,队伍中插队一个人,其他人应该都向后退,那么,应该最后一个人最先后退,否则没有空间供道德败坏者插入,在数据结构也是这样
图解:
DS开篇之作——手撕顺序表_第5张图片

代码实现:

void SLPushFront(SL* psl, SLDatatype x)
{
	assert(psl);
	SLCheckCapacity(psl);

	// 挪动数据
	int end = psl->size - 1;
	while (end >= 0)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[0] = x;
	psl->size++;
	/*SLInsert(psl, 0, x);*/
}

5.顺序尾删

把最后一个数据赋空,然后size减一
图解:
DS开篇之作——手撕顺序表_第6张图片

void SLPopBack(SL* psl)
{
	assert(psl);
	// 暴力检查
	//assert(psl->size > 0);

	 温柔的检查
	if (psl->size == 0)
		return;

	psl->a[psl->size - 1] = 0;
	psl->size--;

	/*SLErase(psl, psl->size - 1);*/
}

6.顺序头删

该问题可以和头插类比,还是经典的排队问题,头部删除一个数据,相当于第一位排队的顾客离开队伍,那么队伍就要前进一个身位,要实现此操作,则离开的顾客的下一个位置的顾客需要上前一个身位,这样第3位顾客可接替第2位顾客的位置,这样第4位顾客可接替第3位顾客的位置,反复直至最后一位顾客向前一个身位,头删问题轻松搞定.
图解:
DS开篇之作——手撕顺序表_第7张图片

void SLPopFront(SL* psl)
{
	assert(psl);
	// 暴力检查
	assert(psl->size > 0);

	/*int start = 0;
	while (start < psl->size-1)
	{
		psl->a[start] = psl->a[start + 1];
		start++;
	}*/

	int start = 1;
	while (start < psl->size)
	{
		psl->a[start-1] = psl->a[start];
		start++;
	}

	psl->size--;

	//SLErase(psl, 0);
}

7.查找

该操作是我们日常生活中使用较频繁的功能。
比如:在QQ群聊里搜索某人的信息
DS开篇之作——手撕顺序表_第8张图片

代码实现

int SLFind(SL* psl, SLDatatype x)
{
	assert(psl);

	for (int i = 0; i < psl->size; i++)
	{
		if (psl->a[i] == x)
		{
			return i;
		}
	}

	return -1;
}

8.修改

该功能使用场景较少,读者朋友们了解即可

void SLModify(SL* psl, int pos, SLDatatype x)
{
	assert(psl);

	assert(0 <= pos && pos < psl->size);

	psl->a[pos] = x;
}

优化

1.插入操作优化

虽然以上操作是正确的,但是头插和尾插都是两个特殊位置,功能不完全,代码有一些冗余,可读性较差,针对此现象,可以对插入操作编写一个函数,可以实现顺序表任意位置的插入数据。
图解:
DS开篇之作——手撕顺序表_第9张图片
代码实现:(pso为数据插入的位置)

void SLInsert(SL* psl, int pos, SLDatatype x)
{
	assert(psl);
	//assert(0 <= pos <= psl->size);
	assert(0 <= pos && pos <= psl->size);

	SLCheckCapacity(psl);

	int end = psl->size - 1;
	while (end >= pos)
	{
		psl->a[end + 1] = psl->a[end];
		--end;
	}

	psl->a[pos] = x;
	psl->size++;
}

2.删除操作优化

增加定位删除功能,通过下标pos来确定删除数据的位置
图解:
DS开篇之作——手撕顺序表_第10张图片
代码实现:

void SLErase(SL* psl, int pos)
{
	assert(psl);
	assert(0 <= pos && pos < psl->size);
	//assert(psl->size > 0);

	int start = pos + 1;
	while (start < psl->size)
	{
		psl->a[start - 1] = psl->a[start];
		++start;
	}

	psl->size--;
}

四.测试用例

数据导入

DS开篇之作——手撕顺序表_第11张图片

头插

DS开篇之作——手撕顺序表_第12张图片

删除第四个数据(3)

DS开篇之作——手撕顺序表_第13张图片

4和5间插入数据100

DS开篇之作——手撕顺序表_第14张图片

查找100的位置

DS开篇之作——手撕顺序表_第15张图片

把数据4修改成-6

DS开篇之作——手撕顺序表_第16张图片

总结:

顺序表的玩法实际上就是对数组的操作,希望读者朋友们很好地掌握!

我追,一个成年人在一群尖叫的孩子中奔跑。但我不在乎。
我追,风拂过我的脸颊,我唇上挂着一个像潘杰希尔峡谷那样大大的微笑。
我追。
——————————————————————————————————《追风筝的人》

你可能感兴趣的:(数据结构,算法,java,c++,开发语言)