追梦之旅【数据结构篇】——详解C语言动态实现顺序表

这篇具有很好参考价值的文章主要介绍了追梦之旅【数据结构篇】——详解C语言动态实现顺序表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。


动态方式建立顺序表 金良兵,追梦之旅【数据结构篇】,数据结构,c语言,算法

   
😎博客昵称:博客小梦
😊最喜欢的座右铭:全神贯注的上吧!!!
😊作者简介:一名热爱C/C++,算法等技术、喜爱运动、热爱K歌、敢于追梦的小博主!

😘博主小留言:哈喽!😄各位CSDN的uu们,我是你的博客好友小梦,希望我的文章可以给您带来一定的帮助,话不多说,文章推上!欢迎大家在评论区唠嗑指正,觉得好的话别忘了一键三连哦!😘
动态方式建立顺序表 金良兵,追梦之旅【数据结构篇】,数据结构,c语言,算法

前言🙌

    哈喽各位友友们😊,我今天又学到了很多有趣的知识现在迫不及待的想和大家分享一下!😘我仅已此文,手把手带领大家学习C语言动态实现顺序表~ 都是精华内容,可不要错过哟!!!😍😍😍

顺序表概念及结构🙌

   在实现顺序表之前,我们先要了解一下什么是顺序表,它的大概结构是怎么样的?其实顺序表是用一段物理地址连续的存储单元依次存储数据元素线性结构,一般情况下采用数组存储。在数组上完成数据的增删查改。
动态方式建立顺序表 金良兵,追梦之旅【数据结构篇】,数据结构,c语言,算法

顺序表一般可以分为:

  1. 静态顺序表:使用定长数组存储元素。
  2. 动态顺序表:使用动态开辟的数组存储。

其实静态实现和动态实现的方法都差不多,但是相比而言动态实现的顺序表的性能更优,实际应用的价值更大,比较灵活。

实现大概思路分析:

首先在头文件先定义结构体和各个功能函数的声明,并把有关的头文件包含上去。各个函数如何实现的,主要是对各个函数的实现,用到realloc动态开辟新节点的空间,用assert断言确保指针有效,通过画图来帮助理清代码实现的思路,指针的指向如何,要考虑哪些情况。然后再测试代码中,将上述代码都进行测试,显示结果。

功能函数的具体实现分析:🙌

尾插函数具体实现:

设计思路分析:

  • 首先设计一个检查容量的函数,保证有空间才能进行插入操作。
  • 将size为下标的元素改为x,别忘了将size++。
  • 或者实现任意插函数之后,而尾插作为其一种特殊情况,可以通过调用任意插函数来实现尾插的功能
//尾插
void SeqListPushBack(SL* p, DataSeqList x)
{
	/*SeqListCheckCapacity(p);
	p->arr[p->size] = x;
	p->size++;*/
	SeqListInsert(p, p->size, x);
}

尾删函数具体实现:

设计思路分析:

  • 先assert检查顺序表的元素个数,如果没有元素就不用再删了
  • 直接将size减减即可。这样其有效个数就少了一个,十分简单。
  • 或者实现任意删函数之后,而尾删作为其一种特殊情况,可以通过调用任意删函数来实现尾删的功能
//尾删
void SeqListPopBack(SL* p)
{
	/*assert(p->size);
	p->size--;*/
	SeqListEraes(p, p->size - 1);
}

头插函数具体实现:

设计思路分析:

  • 首先设计一个检查容量的函数,保证有空间才能进行插入操作。
  • 注意挪动数据如何挪,将控制条件控制好即可。
  • 将首元素改为x,别忘了将size++。
  • 或者实现任意插函数之后,而头插作为其一种特殊情况,可以通过调用任意插函数来实现头插的功能
//头插
void SeqListPushFront(SL* p, DataSeqList x)
{
	//SeqListCheckCapacity(p);
	挪动数据
	//int end = p->size - 1;
	//while (end >= 0)
	//{
	//	p->arr[end + 1] = p->arr[end];
	//	end--;
	//}
	//p->arr[0] = x;
	//p->size++;
	SeqListInsert(p,0, x);
}

头删插函数具体实现:

设计思路分析:

  • 先assert检查顺序表的元素个数,如果没有元素就不用再删了。
  • 注意数据挪动,可以采用画图分析的方法控制挪动数据的控制条件。
  • 不要忘了将size-减减
  • 或者实现任意删函数之后,而头删作为其一种特殊情况,可以通过调用任意删函数来实现头删的功能
//头删
void SeqListPopFront(SL* p)
{
	删完就不用删了
	//assert(p->size);
	//int begin = 1;
	//while (begin < p->size)
	//{
	//	p->arr[begin - 1] = p->arr[begin];
	//	begin++;
	//}
	//p->size--;
	SeqListEraes(p, 0);
}

任意插函数具体实现:

设计思路分析:

  • 先判断容量,有空间才进行插入操作。
  • 检查插入的合法性,在pos >= 0 && pos <= p->size 的范围才能进行插入
  • 注意数据挪动,可以采用画图分析的方法控制挪动数据的控制条件。
  • 别忘了将size加加
//任意插
void SeqListInsert(SL* p,int pos ,DataSeqList x)
{
	SeqListCheckCapacity(p);
	assert(pos >= 0 && pos <= p->size);
	int end = p->size - 1;
	while (end >= pos)
	{
		p->arr[end + 1] = p->arr[end];
		end--;
	}
	p->arr[pos] = x;
	p->size++;

}

任意删函数具体实现:

设计思路分析:

  • 先判断顺序表有没有数据,没有就不用删了。
  • 检查删的位置的合法性,在pos >= 0 && pos < p->size的范围才能进行删除。
  • 注意数据挪动,可以采用画图分析的方法控制挪动数据的控制条件。
  • 别忘了将size减减。
//任意删
void SeqListEraes(SL* p, int pos)
{
	//删完就不用删了
	assert(p->size);
	//删的合法性判断
	assert(pos >= 0 && pos < p->size);
	int begin = pos+1;
	while (begin < p->size)
	{
		p->arr[begin - 1] = p->arr[begin];
		begin++;
	}
	p->size--;
}

销毁顺序表函数具体实现:

设计思路分析:
因为顺序表的空间建立是动态开辟的,动态开辟的空间需要手动free释放

/销毁
void SeqListDestory(SL* p)
{
	free(p->arr);
	p->arr = NULL;
	p->capacity = p->size = 0;
}

查找函数具体实现:

设计思路分析:
这个比较简单,直接写个循环遍历一遍,找到了x就返回它的下标,找不到返回-1.

//查找
int SeqListFind(SL* p, DataSeqList x)
{
	assert(p);
	for (int i = 0; i < p->size; i++)
	{
		if (p->arr[i] == x)
		{
			return i;
		}
	}
	return -1;
}

检查容量函数具体实现:

设计思路分析:

  • 分为没有空间和空间满了两种情况进行。
  • 如果没有空间,就显动态分配四个数据大小的空间。
  • 如果空间存储满了,就动态扩容到原来的2倍空间
//检查容量
void SeqListCheckCapacity(SL* p)
{
	if (p->size == p->capacity)
	{
		int newcapacity = p->capacity == 0 ? 4 : p->capacity * 2;
		DataSeqList* tem = realloc(p->arr, newcapacity * sizeof(DataSeqList));
		assert(tem);
		p->arr = tem;
		p->capacity = newcapacity;
	}
}

初始化函数具体实现:

设计思路分析:
将p->arr = NULL;p->capacity = p->size = 0;

//初始化
void SeqListInit(SL* p)
{
	assert(p);
	p->arr = NULL;
	p->capacity = p->size = 0;
}

打印函数具体实现:

设计思路分析:
这个比较简单,直接写个循环遍历一遍打印即可。

//打印
void SeqListPrintf(SL* p)
{
	int i = 0;
	for (i = 0; i < p->size; i++)
	{
		printf("%d ", p->arr[i]);
	}
	printf("\n");
}

头文件全部源码分享🙌

这里负责函数功能的声明和库函数头文件的包含,写任何一个项目时,可以先把头文件编写好,也就是理清一下项目需要实现哪些功能函数,整理一下项目的整体思路。

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

#define DataSeqList int

typedef struct SeqList
{
	DataSeqList* arr;
	int size;
	int capacity;
}SL;

//初始化
void SeqListInit(SL* p);
//尾插
void SeqListPushBack(SL* p, DataSeqList x);
//尾删
void SeqListPopBack(SL* p);
//头插
void SeqListPushFront(SL* p, DataSeqList x);
//头删
void SeqListPopFront(SL* p);
//任意插
void SeqListInsert(SL* p, int pos, DataSeqList x);
//任意删
void SeqListEraes(SL* p, int pos);
//打印
void SeqListPrintf(SL* p);
//销毁
void SeqListDestory(SL* p);
//查找
int SeqListFind(SL* p, DataSeqList x);
//检查容量
void SeqListCheckCapacity(SL* p);

功能文件全部源码分享🙌


#include"SeqList.h"

//初始化
void SeqListInit(SL* p)
{
	assert(p);
	p->arr = NULL;
	p->capacity = p->size = 0;
}

//尾插- 会遇到三种情况
// 1 - 没有空间    2 - 空间不足,要扩容(查容量)  3 - 空间足够,插入数据

//检查容量
void SeqListCheckCapacity(SL* p)
{
	if (p->size == p->capacity)
	{
		int newcapacity = p->capacity == 0 ? 4 : p->capacity * 2;
		DataSeqList* tem = realloc(p->arr, newcapacity * sizeof(DataSeqList));
		assert(tem);
		p->arr = tem;
		p->capacity = newcapacity;
	}
}

//打印
void SeqListPrintf(SL* p)
{
	int i = 0;
	for (i = 0; i < p->size; i++)
	{
		printf("%d ", p->arr[i]);
	}
	printf("\n");
}

//尾插
void SeqListPushBack(SL* p, DataSeqList x)
{
	/*SeqListCheckCapacity(p);
	p->arr[p->size] = x;
	p->size++;*/
	SeqListInsert(p, p->size, x);
}

//尾删
void SeqListPopBack(SL* p)
{
	/*assert(p->size);
	p->size--;*/
	SeqListEraes(p, p->size - 1);
}
//头插
void SeqListPushFront(SL* p, DataSeqList x)
{
	//SeqListCheckCapacity(p);
	挪动数据
	//int end = p->size - 1;
	//while (end >= 0)
	//{
	//	p->arr[end + 1] = p->arr[end];
	//	end--;
	//}
	//p->arr[0] = x;
	//p->size++;
	SeqListInsert(p,0, x);
}
//头删
void SeqListPopFront(SL* p)
{
	删完就不用删了
	//assert(p->size);
	//int begin = 1;
	//while (begin < p->size)
	//{
	//	p->arr[begin - 1] = p->arr[begin];
	//	begin++;
	//}
	//p->size--;
	SeqListEraes(p, 0);
}

//任意插
void SeqListInsert(SL* p,int pos ,DataSeqList x)
{
	SeqListCheckCapacity(p);
	assert(pos >= 0 && pos <= p->size);
	int end = p->size - 1;
	while (end >= pos)
	{
		p->arr[end + 1] = p->arr[end];
		end--;
	}
	p->arr[pos] = x;
	p->size++;

}
//任意删
void SeqListEraes(SL* p, int pos)
{
	//删完就不用删了
	assert(p->size);
	//删的合法性判断
	assert(pos >= 0 && pos < p->size);
	int begin = pos+1;
	while (begin < p->size)
	{
		p->arr[begin - 1] = p->arr[begin];
		begin++;
	}
	p->size--;
}

//销毁
void SeqListDestory(SL* p)
{
	free(p->arr);
	p->arr = NULL;
	p->capacity = p->size = 0;
}

//查找
int SeqListFind(SL* p, DataSeqList x)
{
	assert(p);
	for (int i = 0; i < p->size; i++)
	{
		if (p->arr[i] == x)
		{
			return i;
		}
	}
	return -1;
}

测试文件代码🙌

#define _CRT_SECURE_NO_WARNINGS 1

#include"SeqList.h"

void test1()
{
	SL s;
	SeqListInit(&s);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrintf(&s);
	SeqListPopBack(&s);
	SeqListPopBack(&s);
	SeqListPrintf(&s);

	SeqListPushFront(&s, 10);
	SeqListPushFront(&s, 20);
	SeqListPushFront(&s, 30);
	SeqListPushFront(&s, 40);
	SeqListPrintf(&s);

	SeqListPopFront(&s);
	SeqListPopFront(&s);
	SeqListPrintf(&s);
	SeqListDestory(&s);



}

void test2()
{
	SL s;
	SeqListInit(&s);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrintf(&s);
	SeqListInsert(&s, 3, 30);
	SeqListPrintf(&s);
	SeqListEraes(&s, 3);
	SeqListEraes(&s, 2);
	SeqListPrintf(&s);

	SeqListDestory(&s);
}
void test3()
{
	SL s;
	SeqListInit(&s);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrintf(&s);
	SeqListInsert(&s, 3, 30);
	SeqListEraes(&s, 2);
	SeqListPrintf(&s);
	SeqListDestory(&s);
}

void test4()
{
	SL s;
	printf("尾插数据1,2,3,4,5\n");
	SeqListInit(&s);
	SeqListPushBack(&s, 1);
	SeqListPushBack(&s, 2);
	SeqListPushBack(&s, 3);
	SeqListPushBack(&s, 4);
	SeqListPushBack(&s, 5);
	SeqListPrintf(&s);
	printf("头插数据10, 20 , 30\n");
	SeqListPushFront(&s, 10);
	SeqListPushFront(&s, 20);
	SeqListPushFront(&s, 30);
	SeqListPrintf(&s);
	SeqListDestory(&s);
}

int main()
{

	//test1();
	//test2();
	//test3();
	test4();
	return 0;
}

部分功能测试结果图:
动态方式建立顺序表 金良兵,追梦之旅【数据结构篇】,数据结构,c语言,算法

总结撒花💞

   本篇文章旨在分享详解C语言动态实现顺序表。希望大家通过阅读此文有所收获!😘如果我写的有什么不好之处,请在文章下方给出你宝贵的意见😊。如果觉得我写的好的话请点个赞赞和关注哦~😘😘😘文章来源地址https://www.toymoban.com/news/detail-819941.html

到了这里,关于追梦之旅【数据结构篇】——详解C语言动态实现顺序表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • C语言数据结构一:动态数组

    先说一个概念:数组是一段 连续 的内存空间。存储相同的数据类型。 数组的两个关键点: 连续内存; 相同类型。 首先连续内存:所以为了找到动态数组我们必须找到一个 首元素 地址。(内存 首地址 。) 如果不知道首地址,那无法找到并操作内存空间。 知道首地址了,

    2024年02月06日
    浏览(43)
  • 【数据结构专栏】动态扩容顺序栈详解

      💌 博客内容:顺序栈的原理详解 😀 作  者:陈大大陈 🚀 个人简介:一个正在努力学技术的准前段,专注基础和实战分享 ,欢迎私信! 💖 欢迎大家:这里是CSDN,我总结知识和写笔记的地方,喜欢的话请三连,有问题请私信 😘 😘 😘 目录 顺序栈的定义 结构体定义

    2023年04月09日
    浏览(38)
  • 【数据结构】顺序表的动态分配(步骤代码详解)

    🎈个人主页:豌豆射手^ 🎉欢迎 👍点赞✍评论⭐收藏 🤗收录专栏:数据结构 🤝希望本文对您有所裨益,如有不足之处,欢迎在评论区提出指正,让我们共同学习、交流进步! 在计算机科学中,数据结构是组织和存储数据的方式,它决定了数据如何被存储、检索和操作。

    2024年04月12日
    浏览(65)
  • 数据结构与算法:动态规划(Dynamic Programming)详解

    动态规划(Dynamic Programming,简称DP) 是一种在数学、管理科学、计算机科学、经济学和生物信息学等领域中使用的,通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。动态规划经常被用于求解优化问题。 动态规划的核心思想是将复杂问题分解为更小的子问

    2024年04月25日
    浏览(48)
  • 【数据结构】C语言结构体详解

    目录 前言 一、结构体的定义 二、定义结构体变量 三、结构体变量的初始化 四、使用typedef声明新数据类型名 五、指向结构体变量的指针 总结 🌈嗨!我是Filotimo__🌈。很高兴与大家相识,希望我的博客能对你有所帮助。 💡本文由Filotimo__✍️原创,首发于CSDN📚。 📣如需转

    2024年02月04日
    浏览(48)
  • [C语言][数据结构][动态内存空间的开辟]顺序表的实现!

    目录 零.必备知识 a.顺序表的底层是数组. b.数组在内存中是连续存放的. c.动态内存空间的开辟(malloc,calloc,realloc). 一.顺序表的定义与实现          1.1 顺序表的定义          1.2 顺序表的初始化          1.3 顺序表的销毁          1.4 顺序表容量的检查与调整

    2024年04月09日
    浏览(88)
  • 【数据结构】C语言队列(详解)

    前言: 💥🎈个人主页:​​​​​​Dream_Chaser~ 🎈💥 ✨✨专栏:http://t.csdn.cn/oXkBa ⛳⛳本篇内容:c语言数据结构--C语言实现队列 目录 一.队列概念及结构 1.1队列的概念 1.2队列的结构 二.队列的实现 2.1头文件 2.2链式队列的结构定义 2.3队列接口的定义 2.4初始化队列 2.5判断队列

    2024年02月10日
    浏览(44)
  • 数据结构(C语言)——顺序表详解

    数据结构是计算机存储和组织数据的方式。常用的数据结构有:数组(Array)、栈(Stack)、队列(Queue)、链表(Linked List)、树(Tree)、图(Graph)、堆(Heap)等;而数据结构又可以通过逻辑结构与物理结构进行分类,逻辑结构是指数据元素之间的逻辑关系,也就是数据元

    2024年04月16日
    浏览(39)
  • 【数据结构】栈---C语言版(详解!!!)

    栈:一种特殊的线性表,其只允许在固定的一端进行插入和删除元素操作。 进行数据插入和删除操作的一端称为栈顶,另一端称为栈底 。栈中的数据元素遵守 后进先出LIFO (Last In First Out)的原则。 压栈 :栈的插入操作叫做进栈/压栈/入栈,入数据在栈顶。 出栈 :栈的删除

    2024年02月10日
    浏览(38)
  • 【数据结构】队列---C语言版(详解!!!)

    队列 :只允许在一端进行插入数据操作,在另一端进行删除数据操作的特殊线性表,队列具有 先进先出FIFO (First In First Out) 入队列:进行插入操作的一端称为队尾 出队列:进行删除操作的一端称为队头 入队列 :进行插入操作的一端称为队尾 出队列 :进行删除操作的一端称

    2024年02月10日
    浏览(51)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包