顺序表(动态顺序表)

其实也不知道发啥,就发个前几天刚写好的循序表吧!话不多说,直接上代码

#pragma once
#include<stdio.h>
#include<stdlib.h>
typedef int list;
typedef struct sequential
{
	list* p;
	list size;    //数据的个数
	list capacity;//顺序表的容量
}sl;

void init(sl* a,list x);                 //初始化
void pushfront(sl* a, list x);           //头插
void popfront(sl* a);                    //头删
void pushback(sl* a, list x);            //尾插
void popback(sl* a);                     //尾删
void push(sl* a,  list location, list x);//任意位置插
void pop(sl* a, list location);          //任意位置删
void find(sl* a, list x);                //寻找一个数据
void expansion(sl* a);                   //扩容
void destory(sl* a);                     //释放空间
void print(sl* a);                       //打印
#define _CRT_SECURE_NO_WARNINGS 1
#include"Sequential_list.h"
//初始化
void init(sl* a,list x)
{
	a->capacity = 0;
	a->size = 0;
	a->p = NULL;
	list* tem = NULL;
	tem = (list*)realloc(a->p, sizeof(list) * x);
	if (tem == NULL)
	{
		printf("动态内存开辟失败\n");
		return;
	}
	else
	{
		a->p = tem;
		a->capacity = x;
		a->size = 0;
	}
}
//扩容
void expansion(sl* a)
{
	list* tem = NULL;
	if (a->size == a->capacity)
	{
		tem = (list*)realloc(a->p, ((a->capacity) * 2) * sizeof(list));
		if (tem == NULL)
		{
			printf("扩容失败\n");
			return;
		}
		else
		{
			a->p = tem;
			a->capacity = a->capacity * 2;
		}
	}
}
//释放空间
void destory(sl* a)
{
	free(a->p);
	a->p = NULL;
}
//打印
void print(sl* a)
{
	list i = 0;
	for (i = 0; i < a->size; i++)
	{
		printf("%d ", a->p[i]);
	}
}
//头插
//里面的beagin并不是第一个元素的意思,因为是头插,所以是最后一个元素的小标,起名beagin是因为这个接口函数的功能是头插
void pushfront(sl* a,list x)
{
	if (a->size == a->capacity)
	{
		//如果a->size与a->capacity相等,代表数据已满,要扩容
		//因为a是指针变量,a中存储的是结构体的地址,传给扩容函数后,相当于扩容函数存放的地址是结构体的地址
		expansion(a);
		list beagin = 0;
		if (a->size != 0)
		{
			for (beagin = a->size - 1; beagin >= 0; beagin--)
			{
				a->p[beagin + 1] = a->p[beagin];
			}
			beagin = 0;
			a->p[beagin] = x;
			a->size++;
		}
		else
		{
			beagin = 0;
			a->p[beagin] = x;
			a->size++;
		}
	}
	else if(a->size<a->capacity)
	{
		//严格来说还要判断是否越界,但是,因为数据个数比容量小,而且每次插入的个数是一个,所以就没有判断,而且上面还有数据与相等判断
		list beagin = a->size - 1;
		for (beagin = a->size - 1; beagin >= 0; beagin--)
		{
			a->p[beagin + 1] = a->p[beagin];
		}
		beagin = 0;
		a->p[beagin] = x;
		a->size++;
	}
	else
	{
		printf("程序出错\n");
		//exit(-1)表示程序异常,并且退出
		exit(-1);
	}
}
//尾插
void pushback(sl* a, list x)
{
	//判断一下顺序表中是否含有数据
	if (0 == a->size)
	{
		a->p[a->size] = x;
		a->size++;
	}
	else
	{
		//顺序表中含有数据,所以要判断空间够不够
		if (a->size < a->capacity)
		{
			list end = a->size;
			a->p[end] = x;
			a->size++;
		}
		else if (a->capacity == a->size)
		{
			//相等代表在插入数就不够用,所以要扩容
			expansion(a);
			list end = a->size;
			a->p[end] = x;
			a->size++;
		}
		else
		{
			printf("程序异常\n");
			exit(-1);
		}
	}
}
//头删
void popfront(sl* a)
{
	//先判断一下a->size是否为0
	if (0 == a->size)
	{
		printf("顺序表中没有数据\n");
		exit(-1);
	}
	else
	{
		//数据不是0,判断一下内存是否够用
		if (a->size < a->capacity)
		{
			list beagin = 1;
			for (beagin = 1; beagin < a->size; beagin++)
			{
				a->p[beagin - 1] = a->p[beagin];
			}
			a->size--;
		}
		else if(a->capacity == a->size)
		{
			expansion(a);
			list beagin = 1;
			for (beagin = 1; beagin < a->size; beagin++)
			{
				a->p[beagin - 1] = a->p[beagin];
			}
			a->size--;
		}
		else
		{
			printf("程序异常\n");
			exit(-1);
		}
	}
}
//尾删
void popback(sl* a)
{
	//判断顺序表中的数据是否为0
	if (a->size != 0)
	{
		a->size--;
	}
	else
	{
		printf("程序异常\n");
		exit(-1);
	}
}
//任意位置的插入
void push(sl* a, list location, list x)
{
	//因为是任意位置插入的数据,所以一定要先判断空间够不够用,切记,一定一定要先判断空间够不够用
	if (a->size < a->capacity)
	{
		//插入位置为0且数据个数是0,则相当于是头插入
		if (a->size == 0&&location == 0)
		{
			pushfront(a,x);
		}
		//插入位置不为0,且数据个数为0,这时因为顺序表的规则,只能在数据开始的第一个位置插入数据,但是插入位置不是0,所以异常
		else if (a->size == 0 && location != 0)
		{
			printf("输入位置异常\n");
			exit(-1);
		}
		//数据个数不为0,且插入位置是0,相当于是头插
		else if (a->size != 0 && location == 0)
		{
			pushfront(a, x);
		}
		//当两个都不为0时,就需要挪动数据,需要判断插入位置与数据的大小
		else if (a->size != 0 && location != 0)
		{
			if (location < a->size)
			{
				list end = a->size - 1;
				for (end = a->size - 1; end >= location - 1; end--)
				{
					a->p[end + 1] = a->p[end];
				}
				a->p[location - 1] = x;
				a->size++;
			}
			//此时相当于尾插
			else if (location == a->size)
			{
				pushback(a, x);
			}
			else
			{
				printf("输入位置异常\n");
				exit(-1);
			}
		}
	}
	//空间不够用,所以要扩容
	else if (a->capacity == a->size)
	{
		expansion(a);
	    if (a->size != 0 && location == 0)
		{
			pushfront(a, x);
		}
		//当两个都不为0时,就需要挪动数据,需要判断插入位置与数据的大小
		else if (a->size != 0 && location != 0)
		{
			if (location < a->size)
			{
				list end = a->size - 1;
				for (end = a->size - 1; end >= location - 1; end--)
				{
					a->p[end + 1] = a->p[end];
				}
				a->p[location - 1] = x;
				a->size++;
			}
			//此时相当于尾插
			else if (location == a->size)
			{
				pushback(a, x);
			}
			else
			{
				printf("输入位置异常\n");
				exit(-1);
			}
		}
	}
	else
	{
		printf("程序异常\n");
		exit(-1);
	}
}
//任意位置删除数据
void pop(sl* a, list location)
{
	//因为是删除数据,所以就不用考虑空间够不够用的问题,直接找到位置删除即可
	if (a->size != 0)
	{
		//此时相当于尾删
		if (location == a->size)
		{
			popback(a);
		}
		else if (location < a->size)
		{
			list beagin = location;
			for (beagin = location; beagin < a->size; beagin++)
			{
				a->p[beagin - 1] = a->p[beagin];
			}
			a->size--;
		}
		else
		{
			printf("删除数据异常\n");
			exit(-1);
		}
	}
	else
	{
		printf("数据个数为0,无法删除数据,程序异常\n");
		exit(-1);
	}
}
//寻找一个数据
void find(sl* a, list x)
{
	list count = 0;
	list i = 0;
	list flag = 0;
	if (a->size != 0)
	{
		for (i = 0; i < a->size; i++)
		{
			if (x == a->p[i])
			{
				flag = 1;
				printf("找到了,下标是%d  \n", i);
				count++;
			}
			else;
		}
		if (1 == flag)
		{
			printf("它的个数是%d \n", count);
		}
		else
		{
			printf("找不到\n");
		}
	}
	else
	{
		printf("程序异常\n");
		exit(-1);
	}
}
#define _CRT_SECURE_NO_WARNINGS 1
#include"Sequential_list.h"
void test()
{
	sl st;
	init(&st,4);
	expansion(&st);
	/*pushfront(&st, 1);
	pushfront(&st, 2);
	pushback(&st, 10);
	pushback(&st, 11);
	push(&st, 3, 3);
	push(&st, 4, 666);
	pop(&st, 1);
	popfront(&st);
	popback(&st);
	print(&st);
	find(&st, 666);*/

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

大家可以看到,我的三个文件依次是头文件,测试文件,最后汇总的文件,其实顺序表的思想很简单,就是我们所学的数组的原理,就是插入,删除的思想,思想还是和数组一样。不同点就是扩容的这里,我用的是realloc函数,因为这个函数我个人感觉比malloc函数好用。还有就是,我们一般扩容是扩两倍,避免扩大了浪费空间。然后就是我写这么多的原因就是我不管写那个接口函数,基本都判断了顺序表内没有数据的情况。在也没啥注意点说了。

最后,希望大家能支持一下吧!谢谢

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值