数据结构——C语言实现顺序表-创新互联

数据结构——顺序表 顺序表的基本结构

目前创新互联建站已为1000+的企业提供了网站建设、域名、网络空间、网站改版维护、企业网站设计、宁强网站维护等服务,公司将坚持客户导向、应用为本的策略,正道将秉承"和谐、参与、激情"的文化,与客户和合作伙伴齐心协力一起成长,共同发展。文章目录
    • 数据结构——顺序表
      • 顺序表的基本结构
      • 建立变量
      • 初始化与释放
      • 创建动态空间
    • 插入数据、删除数据
      • 头部插入数据
      • 头部删除数据
      • 尾部增加数据
      • 尾部删除数据
      • 指定下标增加数据)
      • 指定下标删除数据
      • 调试
      • 查找
      • 查找删除
      • 源码
          • 主函数
          • 声明

数据是依次存储的,具有连续性,是数据连续性不是数字大小连续性。

顺序表分为静态和动态

静态基本就是空间是固定的,需要自己修改;

动态的没有空间就自动扩容。

建立变量
typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{SLDataType* a;
	int size;//记录存储多少个有效数据
	int capicity;//容量空间
}SL;

这整个变量也可以叫做接口,typedef就是容易修改的,设一个变量去表示所对应的类型。

初始化与释放
//初始化
//断言很重要
void SLInit(SL* ps)
{assert(ps);
	ps->a = NULL;
	ps->size = 0;
	ps->capicity = 0;
}
//初始化,先判断指针传过来的数据是否为空指针,然后再对指针内容去初始化。

//释放
void SLInit(SL* ps)
{assert(ps);
	ps->a = NULL;
	ps->size = 0;
	ps->capicity = 0;
}



创建动态空间
void SLCheckCapacity(SL* ps)
{assert(ps);
	//扩容
	if (ps->size == ps->capicity)//判断存了数据和大小是否相等,如果相等就是满了
	{int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;//如果=0就返回4,不等于就返回2倍
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
		if (tmp == NULL)
		{	perror("realloc fail");
			exit(-1);//异常结束
		}
		ps->a = tmp;//扩容后地址,可能异地扩容所以要给一个新地址
		ps->capicity = newcapicity;//扩容成功大小
	}
}
插入数据、删除数据 头部插入数据
void SLPushFront(SL* ps, SLDataType x)
{assert(ps);
	SLCheckCapacity(ps);//不管增加什么数据都要判断一下内存容量,不够就扩容
	int end = ps->size - 1;
	while (end >= 0)
	{ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[ps->size] = x;
	ps->size++;

}
头部删除数据
void SLPopFront(SL* ps)
{assert(ps);
	int begin = 1;//从一开始是为了覆盖下标为0的数据,达到删除效果
	assert(ps->size >0);//所存数据必须大于等于一个
	while (begin< ps->size)//size-1才是最后一个数据的下标
	{ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;//操作完后就把空间删除
}
尾部增加数据

在这里插入图片描述

//尾部的数据直接添加就行,因为当前的ps->a[ps->size]的下标就是在size的位置,然后size++是要确保size要指向最后一个数据的下一个起始位置
void SLPushBack(SL* ps, SLDataType x)
{assert(ps);
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}
尾部删除数据

在这里插入图片描述

//尾部删除就直接size直接减一不打印就行,就可以达到删除效果
void SLPopBack(SL* ps)
{assert(ps);
	//assert(ps);
 温柔的检查
//if (ps->size == 0)
//{//return;
//}
// 暴力的检查
	assert(ps->size >0);//如果报错会直接输出有错误,上述温柔的检查就直接结束
	ps->size--;  
}
指定下标增加数据)

在这里插入图片描述

void SLInsert(SL* ps, size_t pos, SLDataType x)
{assert(ps);
	assert(ps->size >= pos);
	assert(pos >= 0);//判断下标区间
	SLCheckCapacity(ps);//挪动前判断内存是否足够
	int end = ps->size-1;//挪动数据
	while (end >= pos)//移动到下标那位就行,从后面挪
	{ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[ps->size] = x;//挪完后,下标就在pos的位置,直接赋值
	ps->size++;
}
指定下标删除数据

在这里插入图片描述

void SLErase(SL* ps, size_t pos)
{assert(ps);
	assert(ps->size >pos);//尾删就是size-1的位置
	assert(pos >= 0);
	int begin = pos+1;//这里为什么是1呢?因为如果第一个(下标为0)需要删除的话就是直接可以用下标为1的去覆盖他
	while (begin< ps->size)//数据大的下标是size-1
	{ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}
//while (begin >= pos && begin< ps->size)已经定义了begin就取大区间就行
//{//	ps->a[begin - 1] = ps->a[begin];
//	begin++;
//}
// 一开始写的就是这么烂,虽然说效果差不多,哈哈哈。
调试
//这里举例说一下
void TestSeqList1()
{//要传地址才能修改
	SL s1;
	SLInit(&s1);//初始化
	SLPushBack(&s1,1);
	SLPushBack(&s1, 2);
	SLPushBack(&s1, 3);
	SLPushBack(&s1, 4);
	SLPrint(&s1);

	SLDestroy(&s1);//销毁
}
int main()
{TestSeqList1();
	return 0;
}
//调试的话就是最好是做好一个调试一个,先别写菜单,写菜单就不那么便于调试
//调试完再写菜单
查找
int SLFind(SL* ps, SLDataType x, int begin)
{assert(ps);
	for (int i = begin; i< ps->size; i++)
	{if (ps->a[i] == x)//等于那个值就有就返回下标
		{	return i;
		}
	}

	return -1;
}
查找删除
//分两种类型
//删除一个,删除全部

int SLFind(SL* ps, SLDataType x, int begin)
{assert(ps);
	for (int i = begin; i< ps->size; i++)
	{if (ps->a[i] == x)
		{	return i;//返回下标
		}
	}

	return -1;
}
//首先我们要接收返回值
//假设删除4,然后从下标0开始
int SLF=SLFind(&s1, 4, 0);
if(SLF!=-1)
{ SLErase(&s1, SLF);//调用下标删除函数
}
//删除全部
int SLF=SLFind(&s1, 4, 0);
while(SLF!=-1)
{ SLErase(&s1, SLF);//调用下标删除函数
   SLF=SLFind(&s1, 4, SLF);//这次的下标换成上一次删除下标的位置,减少重复计算
}
源码 主函数
#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"
int main()
{SL s;
	SLInit(&s);
	int option = 0;
	int val = 0;
	do
	{menu();
		printf("请输入你的操作:>");
		scanf("%d", &option);
		switch (option)
		{case 1:
			printf("请依次输入你要尾部插入的数据,以-1结束");
			scanf("%d", &val);
			while (val != -1)
			{		SLPushBack(&s, val);
				scanf("%d", &val);
			}
			break;
		case 2:
			SLPopBack(&s);
			break;
		case 3:
			printf("请依次输入你要在头部插入的数据,以-1结束");
			scanf("%d", &val);
			while (val != -1)
			{		SLPushFront(&s, val);
				scanf("%d", &val);
			}
			break;
		case 4:
			SLPopFront(&s);
			break;
		case 5:
			SLPrint(&s);
			break;
		default:
			break;
		}
	} while (option != -1);

	SLDestroy(&s);

	return 0;
}
声明
#define _CRT_SECURE_NO_WARNINGS 1
#pragma once
#include#include#include
静态顺序表
//#define N    10
//typedef int SLDataType;//方便修改创建变量
//typedef struct seqList
//{//	SLDataType a[N];
//	int size;//记录存储多少个有效数据
//}SL;
//

//动态顺序表--按需要扩容
typedef int SLDataType;//方便修改创建变量
typedef struct seqList
{SLDataType* a;
	int size;//记录存储多少个有效数据
	int capicity;//容量空间
}SL;
//打印
void SLPrint(SL* ps);
//初始化
void SLInit(SL* ps);
//销毁
void SLDestroy(SL* ps);
//检查空间,如果满了,进行增容  公共检查扩容
void SLCheckCapacity(SL* ps);


// 尾插尾删
void SLPushBack(SL* ps, SLDataType x);
void SLPopBack(SL* ps);


// 头插头删
void SLPushFront(SL* ps, SLDataType x);
void SLPopFront(SL* ps);


//pos 下标
// 顺序表在pos位置插入x
void SLInsert(SL* ps, size_t pos, SLDataType x);
// 顺序表删除pos位置的值
void SLErase(SL* ps, size_t pos);

//查找
int  SLFind(SL* ps, SLDataType x,int begin);

#####实现函数

#define _CRT_SECURE_NO_WARNINGS 1
#include"seqList.h"


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

void SLCheckCapacity(SL* ps)
{assert(ps);
	//扩容
	if (ps->size == ps->capicity)
	{int newcapicity = ps->size == 0 ? 4 : ps->capicity * 2;
		SLDataType* tmp = (SLDataType*)realloc(ps->a, newcapicity * sizeof(SLDataType));
		if (tmp == NULL)
		{	perror("realloc fail");
			exit(-1);
		}
		ps->a = tmp;//扩容后地址
		ps->capicity = newcapicity;//扩容成功大小
	}
}

void SLInit(SL* ps)
{assert(ps);
	ps->a = NULL;
	ps->size = 0;
	ps->capicity = 0;
}

void SLDestroy(SL* ps)
{assert(ps);
	if (ps->a)
	{free(ps->a);
		ps->a = NULL;
		ps->size = 0;
		ps->capicity = 0;
	}
}



void SLPushBack(SL* ps, SLDataType x)
{assert(ps);
	
	SLCheckCapacity(ps);
	ps->a[ps->size] = x;
	ps->size++;
}

void SLPopBack(SL* ps)
{assert(ps);
	assert(ps->size >0);
	ps->size--;
}




void SLPushFront(SL* ps, SLDataType x)
{assert(ps);
	SLCheckCapacity(ps);
	int end = ps->size - 1;
	while (end >= 0)
	{ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[ps->size] = x;
	ps->size++;

}

void SLPopFront(SL* ps)
{assert(ps);
	int begin = 1;
	assert(ps->size >0);
	while (begin< ps->size)
	{ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}


void SLInsert(SL* ps, size_t pos, SLDataType x)
{assert(ps);
	assert(ps->size >= pos);
	assert(pos >= 0);
	SLCheckCapacity(ps);
	int end = ps->size-1;
	while (end >= pos)
	{ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[ps->size] = x;
	ps->size++;
}
void SLErase(SL* ps, size_t pos)
{assert(ps);
	assert(ps->size >= pos);//尾删就是size-1的位置
	assert(pos >= 0);
	int begin = pos+1;
	while (begin< ps->size)
	{ps->a[begin - 1] = ps->a[begin];
		begin++;
	}
	ps->size--;
}

int SLFind(SL* ps, SLDataType x, int begin)
{assert(ps);

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

	return -1;
}

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


分享题目:数据结构——C语言实现顺序表-创新互联
网站地址:http://ybzwz.com/article/csopsd.html