【手撕数据结构】(三)顺序表和链表

这篇具有很好参考价值的文章主要介绍了【手撕数据结构】(三)顺序表和链表。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

一、线性表

🎗️线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串…
🎗️线性表在逻辑上是线性结构,也就说是一条连续的直线。但是在物理结构上并不一定是连续的,线性表在物理上存储时,通常以数组和链式结构的形式存储。
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

二、顺序表

1.概念及结构

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

顺序表的本质是一个数组;要求数据必须从前往后连续存储。

2.关于数组

(1)数组怎么管理?

指针指向数组开始的位置,就能找到后面的位置。

(2)数组的缺陷

数组删除数据时,不能把数据所在的这块空间释放掉,只能把这一片数组空间都释放掉。数组删除元素的方式是挪动覆盖。

(3)数组的优势

下标的随机访问(原因是数组的物理空间连续)
a[i]等价于*(a+i)

(4)怎样弥补数组的缺陷

用链表。链表是一块一块的小空间,不是一个完整的连续空间。
如果有一个指针指向链表的第一个位置,不能找到后面的位置。因为他们是一块一块独立的空间,是多次malloc出来的,它们之间在地址上是没有关联的。
要想找到下一个位置,就得在上一个位置处存一个指针,指针指向下一个地址。
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
(二分查找不能在链表中使用,能在数组中使用;
排序不能在链表中使用,能在数组中使用)

3.顺序表分类

🎗️静态顺序表

使用定长数组存储元素。

#define N 7
typedef int SLDataType;
typedef struct SeqList {
	SLDataType array[N];  //定长数组
	int size;     //有效数据的个数
}SeqList;

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
总结:
静态顺序表缺点:空间是固定的,给小了不够用,给多了浪费

🎗️动态顺序表

使用动态开辟的数组存储。

typedef int SLDataType;
typedef struct SeqList {
	SLDataType* array;  //指向动态开辟的数组
	int size;  //存储的有效数据个数(知道什么时候扩容)
	int capacity;  //容量空间的大小
};

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

4.接口实现

静态顺序表只适用于确定知道需要存多少数据的场景。静态顺序表的定长数组导致N定大了,空间开多了浪费,开少了不够用。所以现实中基本上都是使用动态顺序表,根据需要动态的分配空间大小,所以我们下面实现动态顺序表。

(1)思路

建立三个文件
SeqList.c写接口的实现
SeqList.h写接口的声明
test.c写调用测试接口

(2)SeqList.h文件代码

首先,在里面定义动态顺序表的结构体
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能1:顺序表初始化

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

🎗️注意:在形参部分不要写成下面这样:
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
如果写成这样,就会出现经典的传值传参问题。此时,传过去的是值,实参传给形参,是一种拷贝。把s传给形参sl,形参sl变量的改变不会影响实参s,因为他们是在两个栈帧里面。
所以不要传结构体的值,而要传结构体的地址。

功能2:销毁顺序表

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能3:尾插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能4:头插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能5:尾删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能6:头删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能7:打印

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能8:在pos位置处插入数据

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能9:在pos位置处删除数据

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能10:查找,找到返回下标,没有找到返回-1

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

功能11:修改pos位置处的值

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

完整代码展示
#define _CRT_SECURE_NO_WARNINGS 1

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


typedef int SLDataType;
typedef struct SeqList {
	SLDataType* a;
	int size;
	int capacity;
}SL;

void SLInit(SL* psl);//顺序表初始化
void SlDestroy(SL* psl);//销毁顺序表
void SLPushBack(SL* psl, SLDataType x);//尾插
void SLPushFront(SL* psl, SLDataType x);//头插
void SLPopBack(SL* psl);//尾删
void SLPopFront(SL* psl);//头删
void SLPrint(SL* psl);//打印
void SLInsert(SL* psl, int pos, SLDataType x); //在pos位置处插入数据
void SLErase(SL* psl, int pos);  //在pos位置处删除数据(也经常写作SLRemove)
int SLFind(SL* psl, SLDataType x);  //查找,找到返回下标,没有找到返回-1
void SLModify(SL* psl, int pos, SLDataType x); //修改pos下标位置的值


(3)SeqList.c文件代码

实现功能1:顺序表初始化

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能2:销毁顺序表

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能3:尾插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

辅助功能:检查容量

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能4:头插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能5:尾删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能6:头删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能7:打印

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能8:在pos位置处插入数据

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

复写功能:复用SLInsert重写头插、尾插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能9:在pos位置处删除数据

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

复写功能:复用SLErase覆写头删、尾删【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
实现功能10:查找

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

实现功能11:修改pos位置处的值

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

完整代码
#define _CRT_SECURE_NO_WARNINGS 1
#include "SeqList.h"

//顺序表初始化
void SLInit(SL* psl) {
	assert(psl);//断言,判断传进来的指针不是空指针,避免后续对空指针解引用出错
	psl->a = (SLDataType*)malloc(sizeof(SLDataType) * 4);//在初始化的时候,最好的写法是一开始就开辟一点空间,开四个(不长也不短,是一个合适的数字)
	if (psl->a == NULL) {                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   
		perror("malloc fail"); 
		return;
	}
	psl->size = 0;
	psl->capacity = 4;
}

//销毁顺序表---意思是把空间还给操作系统,像退房一样
void SLDestroy(SL* psl) {
	assert(psl);
	free(psl->a);
	psl->a = NULL;
	
	psl->size = 0;
	psl->capacity = 0;
}

//尾插
void SLPushBack(SL* psl, SLDataType x) {
	assert(psl);
	psl->a[psl->size] = x;
	psl->size++;
}

//检查容量
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;
	}
}

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

//头插
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++;
}

//由在pos位置插入数据的功能函数重写头插、尾插,复用SLInsert
//void SLPushFront(SL* psl, SLDataType x) {
//	SLInsert(psl, 0, x);
//}
//void SLPushBack(SL* psl, SLDataType x) {
//	SLInsert(psl, psl->size, x);
//}

//尾删
void SLPopBack(SL* psl) {
	assert(psl);
	/*
	顺序表为空时,就不要再删了
	温柔的检查
	if (psl->size == 0) {
		return 0;
	}
	暴力检查(推荐):断言,如果psl->size>0为真就通过了,如果为假就会报错
	assert(psl->size > 0);
	*/
	
	//暴力检查(推荐)
	assert(psl->size > 0);


	//psl->a[psl->size-1]=0;
	//注意这样写不好,万一最后一个位置是0,这样做没意义,如果在数组中的元素类型是double,如今改为0不好,最好改为0.0
	//所以最好的做法是不管尾部数据是多少,只修改顺序表的长度size(有效数据个数)

	psl->size--;
}

//头删
void SLPopFront(SL* psl) {
	assert(psl);
	//暴力检查顺序表是不是为空
	assert(psl->size);

	//把下标start+1的元素挪给下标start处
	int start = 0; 
	while (start < psl->size - 1) {
		psl->a[start] = psl->a[start + 1];
		start++;
	}
	

	/*
	start为1时,将下标start的元素挪给下标start-1处
	int start = 1;
	while (start < psl->size) {
		psl->a[start - 1] = psl->a[start];
		start++;
	}
	*/

	psl->size--;
	
}

//在pos位置处插入数据
void SLInsert(SL* psl,int pos, SLDataType x) {
	assert(psl);
	assert(0 <= pos && pos <= psl->size); //断言pos,不要让插入的位置下标越界

	SLCheckCapacity(psl);  //只要是插入数据,都要关注容量
	int end = psl->size - 1;
	while (end >= pos) {
		psl->a[end + 1] = psl->a[end];
		--end;
	}
	psl->a[pos] = x;
	psl->size++;
}


//在pos位置处删除数据
void SLErase(SL* psl, int pos){
	assert(psl);
	assert(0 <= pos && pos < psl->size); //注意这里的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--;
}

//复用SLErase覆写头删、尾删
//void SLPopFront(SL* psl) {
//	SLErase(psl, 0);
//}
//void SLPopBack(SL* psl) {
//	SLErase(psl, psl->size - 1);
//}


//查找
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;
}

//修改
void SLModify(SL* psl, int pos,SLDataType x) {
	assert(psl);
	assert(0 <= pos && pos < psl->size);

	psl->a[pos] = x;
}

(4)test.c文件代码

测试1:尾插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试2:头插

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试3:尾删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试4:头删

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试5:pos位置处插入

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试6:pos位置处删除

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试7:查找

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

测试8:如果有人传进来空指针怎么办?

【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表
所以说怎么办?

在每个函数内部做一下断言,暴力检查一下。暴力检查的好处是不用调试,出错时会出现错误提示。如下图:
【手撕数据结构】(三)顺序表和链表,数据结构,数据结构,链表

为什么不在main函数中做断言?

写的函数才是给我们用的,不要在调用函数时去检查(也就是说让调用的人去检查,如果他会检查,就不会传空进来了)


总结

顺序表的内容就到这里啦~欢迎大家关注后续内容
👻文章来源地址https://www.toymoban.com/news/detail-754285.html

到了这里,关于【手撕数据结构】(三)顺序表和链表的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • 【数据结构初阶】顺序表和链表(1)

    线性表(linear list) 是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使 用的数据结构,常见的线性表:顺序表、链表、栈、队列、字符串… 线性表在逻辑上是线性结构,也就说是连续的一条直线。但是在物理结构上并不一定是连续的,线性表在物理上

    2024年02月08日
    浏览(242)
  • 数据结构奇妙旅程之顺序表和链表

    ꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶ 个人主页:xiaoxieʕ̯

    2024年02月05日
    浏览(66)
  • 数据结构修炼第二篇:顺序表和链表

    第一章 时间复杂度和空间复杂度 第二章 顺序表,列表 第三章 栈和队列 第四章 二叉树 第五章 排序 作者:🎈乐言🎈 简介:🎈大一学生,目前在致力于c/c++/python,高数的学习,有问题尽管问我,关注后私聊! 持续更新专栏:《c进阶》,《数据结构修炼》 🚀 (优质好文持

    2024年02月02日
    浏览(118)
  • 初阶数据结构之---顺序表和链表(C语言)

    线性表: 线性表(linear list)是n个具有相同特性的数据元素的有限序列。 线性表是一种在实际中广泛使用的数据结构。线性表在逻辑上是线性结构,也就是说是连续的一条直线。但在物理上并不一定是连续的。线性表在物理上存储时,通常以 数组 和 链式结构 的形式存储。

    2024年02月22日
    浏览(67)
  • 【数据结构篇C++实现】- 线性表 - 顺序表和链表

    友情链接:C/C++系列系统学习目录 故事导入: 幼儿园放学时,一个班级的小朋友,一个跟着一个排队出校,有一个打头,有一个收尾,当中的小朋友每一个都知道他前面和后面的一个是谁,就如同一根线把他们串联了起来。如此具有像线一样的性质的表就叫线性表 线性表(

    2024年02月07日
    浏览(57)
  • <数据结构>顺序表和链表的比较|缓存命中率

    💭前言:通过之前对顺序表和链表的实现,我们可以发现在增删查改某些操作上两者的效率前言有所差异,本篇文章将总结二者的异同。 顺序表的实现 http://t.csdn.cn/Lxyg2 单链表的实现 http://t.csdn.cn/rHgjG 双链表的实现 http://t.csdn.cn/j3amO 📚顺序表通过数组来实现的,所以在物理

    2024年02月05日
    浏览(52)
  • 数据结构(王道)——线性表之静态链表&顺序表和链表的比较

      如何定义一个静态链表     初始化静态链表:   静态链表的查找、插入、删除           创: 销:   增、删:   查:   顺序表、链表该如何选择?  

    2024年02月16日
    浏览(126)
  • 顺序表和链表【数据结构】【基于C语言实现】【一站式速通】

    目录 顺序表 顺序表的优点 顺序表的实现 1.结构体的定义 2.初始化数组  3.插入数据 4.其余接口函数的实现 5.释放内存 顺序表的缺陷 单向链表 单向链表的优点 单向链表的实现 1.链表的定义  2.链表的初始化 3.其余接口函数的实现 5.释放内存 单向链表的缺陷 双向链表 双向链

    2024年01月24日
    浏览(53)
  • 探索树形数据结构,通识树、森林与二叉树的基础知识(专有名词),进一步利用顺序表和链表表示、遍历和线索树形结构

      结点之间有分支,具有层次关系 树的定义 : 树 (tree)是n(n≥0)个有限集。 若n = 0,则称为空树; 若n 0,则它满足如下两个条件: 有且仅有一个特定的称为根(Root)的结点; 其余结点可分为m(m≥0)个互不相交的有限集T1,T2,T3,.....,Tm,其中每一个集合本身又是一棵树,并称为根的

    2024年02月01日
    浏览(53)
  • 顺序表和链表

    首先,数据结构中的顺序表和链表都属于线性表。何为线性表?线性表可以描述为: 具有相同数据类型的n个数据元素的有限序列。 形象理解线性表的要素: 幼儿园小朋友放学,需要在校内站成一队,等待家长来接。这是一个 有限 的序列。 总共有几个小朋友,称之为线性表

    2024年02月06日
    浏览(48)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包