其实也不知道发啥,就发个前几天刚写好的循序表吧!话不多说,直接上代码
#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函数好用。还有就是,我们一般扩容是扩两倍,避免扩大了浪费空间。然后就是我写这么多的原因就是我不管写那个接口函数,基本都判断了顺序表内没有数据的情况。在也没啥注意点说了。
最后,希望大家能支持一下吧!谢谢