【数据结构】顺序表(C)

🖊作者 : Djx_hmbb
📘专栏 : C.数据结构
😆今日分享 : 人在接近幸福的时候是最幸福的.
在这里插入图片描述

动态顺序表:

基本功能实现:

初始化:

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

摧毁空间:

//摧毁空间
void DestoryPS(PS* ps)
{
	assert(ps);
	//也可以写成 if(ps->a != NULL)
	if (ps->a)//注意这里是判断数组a是否为空
	{
		free(ps->a);
		ps->a = NULL;
		ps->capacity = ps->size = 0;
	}
}

尾插法:

//尾插法
void PushPS(PS* ps, int x)
{
	//判断空间是否为满
	FullPS(ps);//这里不能写成(&ps)->ps的地址
	//将值尾插到数组中
	ps->a[ps->size] = x;
	ps->size++;
}

判断空间是否为满:

//判断空间是否为满
void FullPS(PS* ps)
{
	assert(ps);
	//如果数组已满,则需要扩容
	if (ps->size == ps->capacity)
	{
		//如果已满,扩容
		int newcapacity = (ps->capacity == 0 ? 4: ps->capacity * 2);
		int* ret = (int*)realloc(ps->a, newcapacity * sizeof(int));
		//判断申请的空间是否为空
		//若为空,则报错
		if (ret == NULL)
		{
			perror("realloc fail");
		    exit(-1);
		}
		//否则,将申请的空间赋给原空间
		ps->a = ret;
		ps->capacity = newcapacity;
	}
}

尾删:

//尾删
void PopPS(PS* ps)
{
	***温柔的解决
	if (ps == NULL)
	{
		perror("realloc fail");
		exit(-1);//异常返回
	}
	//***粗暴的解决
	assert(ps);
	assert(ps->size > 0);//判断大小是否为0
	ps->size--;
}

打印:

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

头插法:

//头插法
void FrontPush(PS* ps, int x)
{
	assert(ps);
	FullPS(ps);
	//挪动数据,往后移一位
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//头插
	ps->a[0] = x;
	ps->size++;
}

头删法:

//头删法
void FrontPop(PS* ps)
{
	assert(ps->size>0);
	int front = 0;
	for (; front < ps->size; front++)
	{
		ps->a[front] = ps->a[front + 1];
	}
	ps->size--;
}

查找位置:

//查找位置
int FindLoacate(PS* ps, int x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			printf("该数字的下标为:%d\n",i);
			return i;
		}
	}
	return -1;
}

随机插入:

//随机插入
void Insert(PS* ps, int pos, int x)//pos为下标位置
{
	assert(ps);
	assert(pos<=ps->size && pos>=0);
	for (int i = ps->size-1; i >= pos; i--)
	{
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}

随机位置删除:

//随机位置删除
void PopLoc(PS* ps, int pos)
{
    assert(ps->size > 0);
	assert(pos < ps->size && pos >= 0);
	for (int i= pos; i < ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

随机数字删除:

//随机数字删除
void PopNum(PS* ps, int x)
{
	assert(ps);
	assert(ps->size > 0);
	int re = FindLoacate(ps, x);
	while (re != -1)//该数字全部删除
	{
		for(int i=re;i<ps->size;i++)
		{
			ps->a[i] = ps->a[i + 1];
		}
		re = FindLoacate(ps, x);
		ps->size--;
	}
}

头文件(Seqlist.h) :

#define _CRT_SECURE_NO_WARNINGS
#pragma once
#include<stdio.h>
#include<assert.h>
#include<stdlib.h>
#define N 10
typedef struct Seqlist
{
	int* a;//定义数组a 存放数组元素
	int size;//定义size 存放数组的大小
	int capacity;//定义capacity  记录申请的空间大小
}PS;

// 初始化
void InitPS(PS* ps);
//摧毁空间
void DestoryPS(PS* ps);

void PrintPS(PS* ps);
//尾插法
void PushPS(PS* ps,int x);
//尾删法
void PopPS(PS* ps);

//判断表是否已满
void FullPS(PS* ps);

//头插法
void FrontPush(PS* ps, int x);
//头删法
void FrontPop(PS* ps);

//查找位置
int FindLoacate(PS* ps, int x);

//随机插入
void Insert(PS* ps, int pos,int x);
//随机位置删除
void PopLoc(PS* ps, int pos);
//随机数字删除
void PopNum(PS* ps, int x);

功能实现文件(Seqlist.c)

#include"Seqlist.h"

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

//摧毁空间
void DestoryPS(PS* ps)
{
	assert(ps);
	//也可以写成 if(ps->a != NULL)
	if (ps->a)//注意这里是判断数组a是否为空
	{
		free(ps->a);
		ps->a = NULL;
		ps->capacity = ps->size = 0;
	}
}

//尾插法
void PushPS(PS* ps, int x)
{
	//判断空间是否为满
	FullPS(ps);//这里不能写成(&ps)->ps的地址
	//将值尾插到数组中
	ps->a[ps->size] = x;
	ps->size++;
}

//判断空间是否为满
void FullPS(PS* ps)
{
	assert(ps);
	//如果数组已满,则需要扩容
	if (ps->size == ps->capacity)
	{
		//如果已满,扩容
		int newcapacity = (ps->capacity == 0 ? 4: ps->capacity * 2);
		int* ret = (int*)realloc(ps->a, newcapacity * sizeof(int));
		//判断申请的空间是否为空
		//若为空,则报错
		if (ret == NULL)
		{
			perror("realloc fail");
		    exit(-1);
		}
		//否则,将申请的空间赋给原空间
		ps->a = ret;
		ps->capacity = newcapacity;
	}
}


//尾删
void PopPS(PS* ps)
{
	***温柔的解决
	if (ps == NULL)
	{
		perror("realloc fail");
		exit(-1);//异常返回
	}
	//***粗暴的解决
	assert(ps);
	assert(ps->size > 0);//判断大小是否为0
	ps->size--;
}

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

//头插法
void FrontPush(PS* ps, int x)
{
	assert(ps);
	FullPS(ps);
	//挪动数据,往后移一位
	int end = ps->size - 1;
	while (end >= 0)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//头插
	ps->a[0] = x;
	ps->size++;
}

//头删法
void FrontPop(PS* ps)
{
	assert(ps->size>0);
	int front = 0;
	for (; front < ps->size; front++)
	{
		ps->a[front] = ps->a[front + 1];
	}
	ps->size--;
}

//查找位置
int FindLoacate(PS* ps, int x)
{
	for (int i = 0; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			printf("该数字的下标为:%d\n",i);
			return i;
		}
	}
	return -1;
}

//随机插入
void Insert(PS* ps, int pos, int x)//pos为下标位置
{
	assert(ps);
	assert(pos<=ps->size && pos>=0);
	for (int i = ps->size-1; i >= pos; i--)
	{
		ps->a[i + 1] = ps->a[i];
	}
	ps->a[pos] = x;
	ps->size++;
}

//随机位置删除
void PopLoc(PS* ps, int pos)
{
    assert(ps->size > 0);
	assert(pos < ps->size && pos >= 0);
	for (int i= pos; i < ps->size; i++)
	{
		ps->a[i] = ps->a[i + 1];
	}
	ps->size--;
}

//随机数字删除
void PopNum(PS* ps, int x)
{
	assert(ps);
	assert(ps->size > 0);
	int re = FindLoacate(ps, x);
	while (re != -1)
	{
		for(int i=re;i<ps->size;i++)
		{
			ps->a[i] = ps->a[i + 1];
		}
		re = FindLoacate(ps, x);
		ps->size--;
	}
}

测试文件(test.c) :


#include"Seqlist.h"
//静态不实用
//动态顺序表

void test01()
{
	PS ps;
 	InitPS(&ps);//初始化

	PushPS(&ps, 1);//尾插法
	PushPS(&ps, 2);
	PushPS(&ps, 3);
	PushPS(&ps, 4);
	PushPS(&ps, 5);
	PopPS(&ps);//尾删法

	PrintPS(&ps);//打印

	DestoryPS(&ps);//毁灭
}
void test02()
{
	PS ps;
	InitPS(&ps);//初始化

	FrontPush(&ps, 1);//头插法
	FrontPush(&ps, 2);
	FrontPush(&ps, 3);
	FrontPush(&ps, 4);
	FrontPush(&ps, 5);
	FrontPop(&ps);//头删法
	FrontPop(&ps);
	FrontPop(&ps);
	FrontPop(&ps);

	PrintPS(&ps);//打印

	DestoryPS(&ps);//毁灭
}
void test03()
{
	PS ps;
	InitPS(&ps);//初始化

	FrontPush(&ps, 1);//头插法
	FrontPush(&ps, 2);
	FrontPush(&ps, 3);
	FrontPush(&ps, 4);
	FrontPush(&ps, 5);

	PrintPS(&ps);//打印
	FindLoacate(&ps, 1);//找位置
	DestoryPS(&ps);//毁灭
}
void test04()
{
	PS ps;
	InitPS(&ps);//初始化

	FrontPush(&ps, 1);//头插法
	FrontPush(&ps, 2);
	FrontPush(&ps, 3);
	FrontPush(&ps, 4);
	FrontPush(&ps, 5);
	Insert(&ps,1,1);//随机插入
	//PopLoc(&ps, 2);
	//PopNum(&ps, 2);
	PrintPS(&ps);//打印
	DestoryPS(&ps);//毁灭
}
int main()
{
	test04();
	return 0;
}

错误 : 在这里插入图片描述

>错误分析:

若一直出现访问冲突,一般有两种情况;
1.空指针(几率大)
2.数据越界(栈溢出)(几率小)
因为栈溢出会显示以下的错误:
在这里插入图片描述

>空指针的解决方案:

: 1 . 如果申请的是动态空间,检查一下头文件有没有写.
eg:
这里我申请了动态内存,但是没有包含头文件
在这里插入图片描述
在这里插入图片描述
加上头文件后,系统将不会报错 .
: 2.检查书写格式有没有错误(要严格按照标准的格式)
eg : 检查需不需要加解引用符号(*)或者取地址符号(&)
: 3.如果都没问题,可以调试一下,看看具体问题是在哪里出错了


感谢家人的阅读,若有不准确的地方 欢迎在评论区指正!

家人们,点个请添加图片描述再走呗~

  • 5
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

D. Star.

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值