当前位置:首页 » 《随便一记》 » 正文

顺序表_m0_61567378的博客

4 人参与  2022年05月17日 12:51  分类 : 《随便一记》  评论

点击全文阅读


静态顺序表

test.c

//顺序表是物理地址连续的存储单元,一次存储数据元素的线性结构,在数组上实现数据增删查改
//顺序表一般可以分为
//1.静态的顺序表:使用定长数组存储
//2.动态的顺序表,使用动态开辟的数组进行存储

//1.连续的物理空间存储——数组
//2.数据必须是从头开始,依次存储,一个一个存

//静态的顺序表,给少了不够用,够多了浪费,不能灵活利用
#include"seqlist.h"

void testseqlist()
{
	SL s;
	seqlistinit(&s);//要把实参的地址传给形参
	seqlistpushback(&s, 1);
	seqlistpushback(&s, 2);
	seqlistpushback(&s, 3);
	seqlistpushback(&s, 4);
	seqlistpushback(&s, 5);
	seqlistpushback(&s, 6);
	seqlistpushback(&s, 7);
	seqlistpushback(&s, 8);
	seqlistpushback(&s, 9);
	seqlistpushback(&s, 10);
	seqlistpushback(&s, 11);

}
int main()
{
	testseqlist();
	return 0;
}

seqlist.c

#include"seqlist.h"
void seqlistinit(SL* ps)
{
	memset(ps->a, 0, sizeof(seqdata)*n);//对数组初始化为0
	ps->sz = 0;
}

void seqlistpushback(SL*ps, seqdata x)
{
	if (ps->sz >= n)
	{
		printf("seqlist is full\n");
		return;
	}
	ps->a[ps->sz] = x;//尾插在sz下一个位置的下标
	ps->sz++;
	//sz可能会超过数组的最大范围,会越界
}

seqlist.h

#pragma once
#include<stdio.h>
#include<string.h>
#define n 10
typedef int seqdata;

typedef struct seqlist
{
	seqdata a[n];
	int sz;
}SL;

void testseqlist();


//初始化一个数组
void seqlistinit(SL* ps);

//尾插
void seqlistpushback(SL*ps, seqdata x);

动态版顺序表

 

seqlist.h

#define _CRT_SECURE_NO_WARNINGS 1;

#pragma once
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<assert.h>
#define n 10
typedef int seqdata;

typedef struct seqlist
{
	seqdata *a;//指向动态开辟的数组
	int sz;//有效数据的个数
	int capacity;//记录容量
}SL;

void testseqlist();


//初始化一个数组
void seqlistinit(SL* ps);

//尾插
void seqlistpushback(SL*ps, seqdata x);

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

//头插
void seqlistpushfront(SL *ps, seqdata x);
//检查容量是否充足
void seqlistcheckcapacity(SL*ps);

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

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

//中间插入
void seqlistinsert(SL*ps, int pos, seqdata x);

//中间删除
void seqlisterase(SL*ps, int pos);

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

//查
void seqlistfind(SL *ps, seqdata x);

//修改
void seqlistmodify(SL *ps,int pos, seqdata x);

seqlist.c

#include"seqlist.h"
void seqlistinit(SL* ps)//对顺序表进行初始化
{
	ps->a = NULL;
	ps->sz = 0;
	ps->capacity = 0;
}


//尾插
void seqlistpushback(SL*ps, seqdata x)
{
	seqlistcheckcapacity(ps);
	ps->a[ps->sz] = x;//尾插在sz下一个位置的下标
	ps->sz++;
	//sz可能会超过数组的最大范围,会越界
}


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

//头插
void seqlistpushfront(SL *ps, seqdata x)//同样面临一个增容的问题,但每次都写增容的代码很麻烦,所以我们可以写一个
{
	seqlistcheckcapacity(ps);
	int end = ps->sz - 1;
	//循环while的写法
	//1.初始条件
	//2.结束条件
	//3.迭代过程
	//头插就是每一位都往后挪,第一个位置空了出来
	
	while (end >= 0)//我们想的结束的条件,而循环写的是继续的条件
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[0] = x;//把第一个元素插入
	ps->sz++;

}

//搞出一个函数原来检查容量是否充足,如果不足就要增容
void seqlistcheckcapacity(SL*ps)
{
	if (ps->sz == ps->capacity)//有效数据对于最大容量,那么我们就要进行扩容
	{
		int newcapacity = ps->capacity == 0 ? 4 : ps->capacity * 2;//一开始sz为0,capacity也为0,所以当等于时有两种情况,
		//1.为开辟空间
		//2.sz到达了capabilities的容量
		//如果一开始的capaci的初值为0,就把capacity改为4,否则就把他扩容两倍
		//我们一般扩2倍,扩一倍浪费时间,扩3倍浪费空间
		seqdata *tmp = (seqdata*)realloc(ps->a, newcapacity * 2 * sizeof(seqdata));
		if (tmp == NULL)
		{
			printf("realloc failur");
			return;
		}
		else
		{
			ps->a = tmp;
			ps->capacity = newcapacity;
		}
	}
}
//尾删
void seqlistpopback(SL*ps)
{
	//假如说sz为0就不用删除了
	//但是如果想用粗暴的方法
	//断言,如果大于0就继续删除,等于0的化就会报错
	assert(ps->sz>0);
	//由sz来标识有多少个有效数据
	//直接把sz--,把有效数据减少就行了
	//如果我们把最后一个数据置为0,再sz--,不合适,因为可能最后一个元素本来就是一个0,或者他并不是int类型,是一个double类型的变量

	ps->sz--;
}
//头删
void seqlistpopfront(SL*ps)
{
	//同时也要预防头没有数据了
	assert(ps->sz > 0);
		int start = 1;
		//前一个都用后一个来覆盖
		while (start < ps->sz)
	{
			ps->a[start - 1] = ps->a[start];//start下标最多到sz-1的位置
			start++;
	}
		//头部数据删除完之后
		//同样sz也要减
		ps->sz--;
}

void seqlistinsert(SL*ps, int pos, seqdata x)
{
	//pos只能再sz有效数据里面进行选择
	assert(pos < ps->sz);
	seqlistcheckcapacity(ps);
	int end = ps->sz - 1;
	while (end>=pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	//直到end挪到小于pos就终止了
	ps->a[pos] = x;//pos是数组的下标
	ps->sz++;
}

void seqlisterase(SL*ps, int pos)
{
	//一次把后面的数据往前挪
	//把pos的位置给覆盖掉
	assert(pos < ps->sz);
	int start = pos + 1;
	while (start < ps->sz)
	{
		ps->a[start-1] = ps->a[start];
		start++;
	}
	ps->sz--;
}


void seqlistdestroy(SL*ps)//malloc出来的空间不销毁就会内存泄露
{
	free(ps->a);
	ps->a = NULL;
	ps->sz = ps->capacity = 0;
}

void seqlistfind(SL *ps, seqdata x)//如果有序的化就可以使用二分查找
{
	//假如是有序的化,就可以用二分查找,但他并不是有序的
	//那么我们就用暴力解法
	int i = 0;
	for (i = 0; i < ps->sz; i++)
	{
		if (ps->a[i] == x)
		{
			return i;//返回x的下标
		}
	}
	return -1;//如果找到的化就返回下标,每找到就返回-1,因为数组里面的下标不可能是-1
}

void seqlistmodify(SL *ps, int pos, seqdata x)
{
	assert(pos < ps->sz);
	ps->a[pos] = x;
}

 test.c

//顺序表是物理地址连续的存储单元,一次存储数据元素的线性结构,在数组上实现数据增删查改
//顺序表一般可以分为
//1.静态的顺序表:使用定长数组存储
//2.动态的顺序表,使用动态开辟的数组进行存储

//1.连续的物理空间存储——数组
//2.数据必须是从头开始,依次存储,一个一个存

//静态的顺序表,给少了不够用,够多了浪费,不能灵活利用
#include"seqlist.h"

void testseqlist()
{
	SL s;
	seqlistinit(&s);//要把实参的地址传给形参
	seqlistpushback(&s, 1);
	seqlistpushback(&s, 2);
	seqlistpushback(&s, 3);
	seqlistpushback(&s, 4);
	seqlistpushback(&s, 5);
	seqlistpushback(&s, 6);
	seqlistpushback(&s, 7);   
	seqlistpushback(&s, 8);
	seqlistpushback(&s, 9);
	seqlistpushback(&s, 10);
	seqlistpushback(&s, 11);
	seqlistpushfront(&s, 0);
	seqlistpushfront(&s, -1);
	seqlistpopfront(&s);
	seqlistpopback(&s);
	seqlistinsert(&s, 0, 20);//0数组的下标
	seqlisterase(&s, 0);
	seqlistprint(&s);
	seqlistdestroy(&s);

}
int main()
{
	testseqlist();
	return 0;
}

随后我会上传一些顺序表的oj


点击全文阅读


本文链接:http://zhangshiyu.com/post/40300.html

数组  顺序  下标  
<< 上一篇 下一篇 >>

  • 评论(0)
  • 赞助本站

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

关于我们 | 我要投稿 | 免责申明

Copyright © 2020-2022 ZhangShiYu.com Rights Reserved.豫ICP备2022013469号-1