【C++】顺序表(千字好文哦)

1.顺序表

1.顺序表

定义:一系列物理连续地址的存储单元,用来存储一系列的数据元素,一般是用数组的形式存储,(但和数组还是有一些区别),用来实现对数据的增删查改

比如数组的成员访问是任意的,我可以创建十个元素长度的数组,在下标为0放一个元素,下标为4放一个元素,其他空着也不初始化

但是顺序表强调的就是连续

还记得我们之前写过的动态版本的通讯录吗

https://blog.csdn.net/weixin_71138261/article/details/127030054?spm=1001.2014.3001.5501

其实我们当初的设想就是,如果只用一个固定大小的数组不够完美,这个数据的大小最好能根据我要放多少个数据来确定,这样不会浪费空间

struct contact
{
	struct People_Information* date;
	int sz;
	int capacity;
};

其实在那个程序里这个部分,我们就用到一个结构体来动态存放数据

这就是一个顺序表的思想

把这个程序里面的顺序表部分拿出来我们再巩固一下

//头文件.h

被注释的地方就是静态的顺序表,用到的不多,所以着重看动态的部分

#define _CRT_SECURE_NO_WARNINGS
#pragrama once //防止头文件被多次包含
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

//static squential list
//#define LEN 10

typedef int Datatype;
//typedef struct SquList
//{
//	int arr[LEN];
//	int size;
//}SL;

//dynamic
typedef struct SquList
{
	Datatype*squ;
	int size;
	int capacity;
}SL;

void SquInit(SL*ps); //初始化
void SquPushBack(SL* ps, Datatype x);  //尾插
void Destory(SL* ps); //销毁
void PopBack(SL* ps);//尾删
void SquPrint(SL* ps);//打印

//函数实现部分.c

函数实现部分,一些增删查改的函数

#define _CRT_SECURE_NO_WARNINGS
#include "sldlist.h"

void SquInit(SL* ps)
{
	assert(ps);
	ps->squ=NULL;
	ps->capacity = 0;
	ps->size = 0;
}

void SquPushBack(SL* ps, Datatype x)
{
	assert(ps);
	if (ps->size == ps->capacity)
	{
		int newcapacity = ps->size == 0 ? 4 : ps->capacity * 2;
		Datatype*tmp=  (Datatype*)realloc(ps->squ, newcapacity * sizeof(Datatype));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(-1);
		}
     ps->squ = tmp;
	 ps->capacity = newcapacity;
	}

	ps->squ[ps->size] = x;
	ps->size++;
}

void Destory(SL* ps)
{
	assert(ps);
	if (ps ->squ)
	{
		free(ps->squ);
		ps ->squ= NULL;
}
}

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

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

//函数主体.c

#define _CRT_SECURE_NO_WARNINGS
#include "sldlist.h"
#include <stdio.h>


int main()
{
	SL sl;
	SquInit(&sl);
	SquPushBack(&sl, 1);
	SquPushBack(&sl, 2);
	SquPushBack(&sl, 3);
	SquPushBack(&sl, 4);
	SquPushBack(&sl, 5);
	SquPrint(&sl);

	SquPushBack(&sl, 7);
	SquPushBack(&sl, 9);
	SquPushBack(&sl, 10);
	SquPrint(&sl);

	PopBack(&sl); 
	SquPrint(&sl);

	Destory(&sl);
	return 0;
}

当然,如果这个顺序表只能尾插尾删,那他也太不合格了

所以我们现在增加一些他的功能,包括头插,头删,尾插,尾删,万能插,万能删(指定位置)

新的程序如下

squential.h

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include <stdlib.h>
typedef  int type;
typedef struct Squential
{
	type* a;
	type size;
	type capacity;

}SL;

void Init(SL* ps);
void PushFront(SL* ps,type x);
void Print(SL* ps);
void Destory(SL* ps);
void Plus(SL* ps);
void PopFront(SL* ps);
void PushBack(SL* ps,type x);
void PopBack(SL* ps);
void Push(SL* ps, type pos,type x );
void Delete(SL* ps, type pos);

squential.c

#define _CRT_SECURE_NO_WARNINGS
#include "squential.h"

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

//判断一下是不是要扩容
void Plus(SL* ps)
{
	assert(ps);
	if (ps->capacity == ps->size)
	{
		type  new = ps->capacity == 0 ? 4 : ps->capacity * 2;
		type* tmp = (type*)realloc(ps->a,new * sizeof(type));
		if (tmp == NULL)
		{
			perror("realloc");
			exit(0);
		}
		ps->a = tmp;
		ps->capacity = new;
	}
}

//头插
void PushFront(SL* ps,type x)
{
	assert(ps);
	Plus(ps);
	if (ps->size == 0)
	{
		ps->a[0] = x;

	}
	else
	{
		type end = ps->size-1;
		while (end >= 0)
		{
			ps->a[end+1] = ps->a[end ];
			end--;
		}
		ps->a[0] = x;
		
	}
ps->size++;
}

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

	}
	printf("\n");
}

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

}

//头删
void PopFront(SL* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("表空\n");
		exit(0);
	}
	else
	{
		type begin = 1;
		while (begin < ps->size)
		{
			ps->a[begin-1] = ps->a[begin ];
			begin++;
		}

	}
	ps->size--;
}

//尾插
void PushBack(SL* ps,type x)
{
	assert(ps);
	Plus(ps);
	if (ps->size == 0)
	{
		ps->a[0] = x;
	}
	else
	{
		ps->a[ps->size] = x;
	}
	ps->size++;
}

//尾删
void PopBack(SL* ps)
{
	assert(ps);
	if (ps->size == 0)
	{
		printf("表空\n");
		exit(0);
	}
	else
	{
		ps->size--;

	}
}

//万能插
void Push(SL* ps,type pos,type x)
{
	assert(ps);
	Plus(ps);
	assert(pos >= 0);
	assert(pos <= ps->size);
	Plus(ps);
	type end= ps->size -1;
	while (end >= pos)
	{
		ps->a[end + 1] = ps->a[end];
		end--;
	}
	ps->a[pos] = x;
	ps->size++;
}

//万能删除
void Delete(SL* ps,type pos)
{
	assert(ps);
	Plus(ps);
	assert(pos >= 0);
	assert(pos <ps->size);
	type begin = pos;
	while (begin < ps->size-1)
	{
		ps->a[begin] = ps->a[begin + 1];
		begin++;
	}
	ps->size--;
}

Test.c

#define _CRT_SECURE_NO_WARNINGS
#include "squential.h"
void Test1(void)
{
	SL sl;
	Init(&sl);
	PushFront(&sl,  1);
	PushFront(&sl, 2);
	PushFront(&sl,3);
    Print(&sl);
	Destory(&sl);

}

void Test2(void)
{
	/*SL sl;
	Init(&sl); //打印表空
	*/

	SL sl;
	Init(&sl);
	PushFront(&sl, 1);
	PushFront(&sl, 2);
	PushFront(&sl, 3);
	Print(&sl); //321


	PopFront(&sl);
	Print(&sl);//21

	PushFront(&sl, 1);
	PushFront(&sl, 2);
	PushFront(&sl, 3);
	Print(&sl);//32121

	PopFront(&sl);
	Print(&sl);//2121

	Destory(&sl);
}
void Test3(void)
{
	SL sl;
	Init(&sl);
	PushBack(&sl, 0);
	Print(&sl);

	PushFront(&sl, 1);
	PushFront(&sl, 2);
	PushFront(&sl, 3);
	Print(&sl);

	PushBack(&sl,4);

	Destory(&sl);
}
void Test4(void)
{
	SL sl;
	Init(&sl);
	PushFront(&sl, 1);
	PushFront(&sl, 2);
	PushFront(&sl, 3);
	PopBack(&sl);
	Print(&sl);
	Destory(&sl);
}
void Test5(void)
{
	SL sl;
	Init(&sl);
	Push(&sl,0, 1);
	Push(&sl, 1,2);
	Push(&sl, 2, 3);
	Push(&sl, 3, 4);
	Print(&sl);
	Destory(&sl);

}
void Test6(void)
{
	SL sl;
	Init(&sl);
	Push(&sl, 0, 1);
	Push(&sl, 1, 2);
	Push(&sl, 2, 3);
	Push(&sl, 3, 4);
	Delete(&sl, 2);
	Print(&sl);
	Destory(&sl);
}
int main()
{
	//Test1();
	//Test2();
	//Test3();
	//Test4();
	//Test5();
	Test6();


	return 0;
}

当然我们还可以在里面丰富很多功能,比如删除重复的数字

//删除所有的x
//找到第一次出现x的位置
type Find(SL* ps,type x,type pos)
{
	assert(ps);
	for (type i = pos; i < ps->size; i++)
	{
		if (ps->a[i] == x)
		{
			return i;
		}
	}
	return - 1;
}

void del(SL* ps, type x)
{
	assert(ps);
	type i = Find(ps, x,0);
	while (i != -1)
	{
		Delete(ps, i);
		i=Find(ps, x,i+1);
	}
}

感谢收看~

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值