IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 数据结构与算法 -> 数据结构—顺序表 -> 正文阅读

[数据结构与算法]数据结构—顺序表

?

目录

顺序表介绍

创建顺序表类型

初始化顺序表

销毁顺序表

打印顺序表

增加数据

头插

尾插

删除数据

头删

尾删

查找数据

修改指定下标的数据

整体代码


顺序表介绍

什么是顺序表?

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

顺序表分为两种:一种是静态顺序表,另一种是动态开辟的顺序表

说简单一点,其实顺序表就是类比数组!

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

创建顺序表类型

typedef int SLDataType;

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

}SL;

声明一个指针a用于动态开辟空间,用size记录当前顺序表中的数据个数,用capacity记录顺序表的容量大小

初始化顺序表

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

初始化就是全部变量置0处理

销毁顺序表

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

因为是在内存的堆上进行动态内存开辟的,所以要及时释放空间,避免内存泄漏

打印顺序表

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

遍历进行打印即可

增加数据

void SeqListCheckCapacity(SL* ps)//检查容量
{    assert(ps);
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}
void  SeqListInsert(SL* ps,int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SeqListCheckCapacity(ps);
	int i = 0;
	for (i=ps->size-1;i>=pos;i--)
	{
		ps->a[i+1] = ps->a[i];//pos后的数据依次往后面挪动
	}
	ps->a[pos] = x;
	ps->size++;
}

增加数据前,我们都要先检查一下空间容量是否已经满了,满了则需要扩容,容量变为原来的2倍,然后就可以在想要的位置pos插入数据了

?

头插

void SeqListPushFront(SL* ps, SLDataType x)//在pos=0的位置插入数据
{   assert(ps);
	SeqListInsert(ps, 0, x);
}

尾插

void SeqListPushBack(SL* ps, SLDataType x)//在size位置插入数据
{   assert(ps);
	SeqListInsert(ps, ps->size, x);
}

在这里我们都可以调用我们的任意下标pos位置插入的函数,即头插就是在0位置处插入数据,尾插就是在size-1位置处插入数据?

删除数据

void SeqListErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos>=0&&pos<=ps->size);
	int i = 0;
	for (i=pos;i<ps->size-1;i++)
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}

从pos下标位置开始,其后的数据从前往后依次向前覆盖,相当于将哪个数据删除了

?

头删

void SeqListPopFront(SL* ps)//删除下标为0的位置的数据
{    assert(ps);
	SeqListErase(ps, 0);
}

尾删

void SeqListPopBack(SL* ps)//删除下标为ps->size - 1的位置的数据
{    assert(ps);
	SeqListErase(ps, ps->size - 1);
}

头删和尾删原理和头插和尾插类似,我们只需要调用在任意位置pos插入的函数,即头删就是在0的位置删除数据,尾删就是在size-1的位置删除数据

查找数据

int SeqListFind(SL* ps, SLDataType x)
{    assert(ps);
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}

	return -1;
}

修改指定下标的数据

void SeqListModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//检查输入下标的合法性
	ps->a[pos] = x;//修改数据
}

整体代码

//SList.h
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include<assert.h>
#include<stdlib.h>


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

}SL;

void SeqListInit(SL* ps);//初始化

void SeqListDestory(SL* ps);//销毁

void SeqListCheckCapacity(SL* ps);//检查容量

void SeqListPopFront(SL* ps);//头删

void SeqListPopBack(SL* ps);//尾删

void SeqListErase(SL* ps, int pos);//直接删

void  SeqListInsert(SL* ps, int pos, SLDataType x);//直接插

void SeqListPushFront(SL* ps, SLDataType x);//头插

void SeqListPushBack(SL* ps, SLDataType x);//尾插

void SeqListPrint(SL* ps);//打印

void SeqListModify(SL* ps, int pos, SLDataType x);//修改指定下标位置元素

int SeqListFind(SL* ps, SLDataType x);//查找数据



//SList.c

void SeqListInit(SL*ps)//初始化
{
	ps->a = NULL;
	ps->size = 0;
	ps->capacity = 0;
}
void SeqListDestory(SL* ps)//销毁
{
	free(ps->a);
	ps = NULL;
	ps->capacity = ps->size = 0;
}
void SeqListCheckCapacity(SL* ps)//检查容量
{
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;
		SLDataType* tmp = (SLDataType)realloc(ps->a, newcapacity * sizeof(SLDataType));
		if (tmp == NULL)
		{
			printf("realloc fail\n");
			exit(-1);
		}
		ps->a = tmp;
		ps->capacity = newcapacity;
	}
}


//头删
void SeqListPopFront(SL* ps)//删除下标为0的位置的数据
{
	SeqListErase(ps, 0);
}
//尾删
void SeqListPopBack(SL* ps)//删除下标为ps->size - 1的位置的数据
{
	SeqListErase(ps, ps->size - 1);
}



//直接删
void SeqListErase(SL* ps, int pos)
{
	assert(ps);
	assert(pos>=0&&pos<=ps->size);
	int i = 0;
	for (i=pos;i<ps->size-1;i++)//从pos下标位置开始,其后的数据从前往后依次向前覆盖
	{
		ps->a[i-1] = ps->a[i];
	}
	ps->size--;
}
//查找数据
int SeqListFind(SL* ps, SLDataType x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}

	return -1;
}

//修改指定下标位置元素
void SeqListModify(SL* ps, int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos < ps->size);//检查输入下标的合法性
	ps->a[pos] = x;//修改数据
}

//直接插
void  SeqListInsert(SL* ps,int pos, SLDataType x)
{
	assert(ps);
	assert(pos >= 0 && pos <= ps->size);
	SeqListCheckCapacity(ps);
	int i = 0;
	for (i=ps->size-1;i>=pos;i--)
	{
		ps->a[i+1] = ps->a[i];//pos后的数据依次往后面挪动
	}
	ps->a[pos] = x;
	ps->size++;
}

//头插
void SeqListPushFront(SL* ps, SLDataType x)//在pos=0的位置插入数据
{
	SeqListInsert(ps, 0, x);
}


//尾插
void SeqListPushBack(SL* ps, SLDataType x)//在size位置插入数据
{
	SeqListInsert(ps, ps->size, x);
}


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

//test.c

void test()
{
	SL a;
  SeqListInit(&a);
  SeqListInsert(&a,0,1);
  SeqListInsert(&a, 1, 2);
  SeqListErase(&a,1);
  SeqListPrint(&a);
}
int main()
{
	test();
	return 0;
}

记得在每个函数传入指针时加入assert(ps);断言报错一下,以防传入空指针!

谢谢各位的观看!

?

  数据结构与算法 最新文章
【力扣106】 从中序与后续遍历序列构造二叉
leetcode 322 零钱兑换
哈希的应用:海量数据处理
动态规划|最短Hamilton路径
华为机试_HJ41 称砝码【中等】【menset】【
【C与数据结构】——寒假提高每日练习Day1
基础算法——堆排序
2023王道数据结构线性表--单链表课后习题部
LeetCode 之 反转链表的一部分
【题解】lintcode必刷50题<有效的括号序列
上一篇文章      下一篇文章      查看所有文章
加:2021-10-26 12:25:59  更:2021-10-26 12:26:05 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/26 8:16:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码