C语言顺序表源码

简介: 顺序表源码

顺序表源码:

SeqList.h文件

#pragma once//防止重复调用/包含#include<stdio.h>#include<stdlib.h>#include<assert.h>//动态顺序表 --按需扩空间typedefintSLDataType;     //为方便维护修改数据类型,重定义顺序表的数据类型typedefstructSeqList//多个数据定义为结构体,{
SLDataType*a;          //想到动态开辟内存函数malloc,定义一个指针,指向动态开辟的数组intsize;               //有效数据个数intcapacity;           //空间容量大小,满了relloc扩容}SL;//typedef重定义voidSLPrint(SL*ps);           //打印函数的声明//void SeqListInit(SL s);       //全称voidSLInit(SL*ps);            //定义一个顺序表voidSLDestroy(SL*ps);         //释放动态开辟的内存voidSLCheckCapacity(SL*ps);   //检查,扩容//尾插尾删voidSLPushBack(SL*ps, SLDataTypex);
voidSLPopBack(SL*ps);               
//头插头删voidSLPushFront(SL*ps, SLDataTypex);
voidSLPopFront(SL*ps);              
//在pos位置插入数据voidSLInsert(SL*ps, intpos, SLDataTypex);
//删除pos位置数据,删除指定位置的数据voidSLErase(SL*ps, intpos);
////查找数据,为实现删除指定数据//int SLFind(SL* ps, SLDataType x);//查找改进,针对有重复数据intSLFind(SL*ps, SLDataTypex, intbegin);

SeqList.c文件

#include"SeqList.h"//引用头文件voidSLInit(SL*ps)
{
assert(ps);
//初始化ps->a=NULL;//结构体指针用->ps->size=0;
ps->capacity=0;
}
//打印函数voidSLPrint(SL*ps)
{
assert(ps);
for (inti=0; i<ps->size; ++i)
    {
printf("%d ", ps->a[i]);
    }
printf("\n");
}
voidSLDestroy(SL*ps)
{
//if(ps->a !=NULL)assert(ps);
if (ps->a)         //为真说明内存开辟成功,需要释放置空    {
free(ps->a);   //释放,free报错往往是越界,或者是释放的地方不对,一般free的时候才会检查越界ps->a=NULL;  //置空ps->size=ps->capacity=0;//顺便修改他俩的值    }
}
voidSLCheckCapacity(SL*ps)//检查,扩容{
assert(ps);
//插入前得开空间,判断空间是否满,否则涉及到越界问题//判断size和capacity是否相等,相等则满,或者还没开辟空间,因为开始时都初始化为0if (ps->size==ps->capacity)
    {
intnewCapacity=ps->capacity==0?4 : ps->capacity*2;//如果是0还没开辟空间,如果不是就直接扩为2倍//ps->a = (SLDataType*)realloc(ps->a, newCapacity * sizeof(SLDataType));//扩容  ,realloc后面的参数是大小,前面的是需要扩容的空间//需要接收地址,因为relloc返回的是新开空间的地址SLDataType*tmp= (SLDataType*)realloc(ps->a, newCapacity*sizeof(SLDataType));//扩容  ,realloc后面的参数是大小,前面的是需要扩容的空间//需要用临时变量tmp接收地址,因为relloc返回的是新开空间的地址if (tmp==NULL)//判断扩容是否成功        {
perror("relloc fail");
exit(-1);//异常终止程序,0代表正常终止        }
ps->a=tmp;
ps->capacity=newCapacity;
    }
}
//尾插O(1)voidSLPushBack(SL*ps, SLDataTypex)
{
/*assert(ps);SLCheckCapacity(ps);ps->a[ps->size] = x;ps->size++;*/SLInsert(ps, ps->size, x);//复用}
//尾删voidSLPopBack(SL*ps)
{
//温柔的检查/*if (ps->size == 0){return;}*///暴力的检查(断言)assert(ps->size>0);//会直接报错,为真继续走,为假结束//ps->a[ps->size - 1] = 0;//将最后一个数据改为0,再size--,意义不大,因为print是以size为基础的,只会访问size前面的数据,再插入数据会将无效数据直接覆盖ps->size--;
//SLErase(ps, ps->size - 1);//复用}
//头插O(N)voidSLPushFront(SL*ps, SLDataTypex)
{
//assert(ps);//SLCheckCapacity(ps);////挪动数据//int end = ps->size - 1;//size-1是最后一个元素的下标//while (end >= 0)//{//  ps->a[end + 1] = ps->a[end];//  --end;//}//ps->a[0] = x;//ps->size++;SLInsert(ps, 0, x);//复用}
//头删voidSLPopFront(SL*ps)
{
/*assert(ps);assert(ps->size>0);int begin = 1;while (begin < ps->size){ps->a[begin - 1] = ps->a[begin];begin++;}ps->size--;*/SLErase(ps, 0);//复用}
//在pos位置插入数据voidSLInsert(SL*ps, intpos, SLDataTypex)
{
assert(ps);
assert(pos>=0);
assert(pos<=ps->size);//必须是连续存储SLCheckCapacity(ps);//考虑到后面空间不够可能越界intend=ps->size-1;
while (end>=pos)
    {
ps->a[end+1] =ps->a[end];
end--;
    }
ps->a[pos] =x;
ps->size++;
}
//删除pos位置数据voidSLErase(SL*ps, intpos)
{
assert(ps);
assert(pos>=0);
assert(pos<ps->size);
//assert(ps->size > 0);//挪动数据覆盖intbegin=pos+1;
while (begin<ps->size)
    {
ps->a[begin-1] =ps->a[begin];
begin++;
    }
ps->size--;
}
////查找//int SLFind(SL* ps, SLDataType x)//{//  assert(ps);//  for (int i = 0; i < ps->size; i++)//  {//      if (ps->a[i] == x)//      {//          return i;//      }//  }//  return -1;//}//查找改进,针对有重复数据intSLFind(SL*ps, SLDataTypex,intbegin)
{
assert(ps);
for (inti=begin; i<ps->size; i++)
    {
if (ps->a[i] ==x)
        {
returni;
        }
    }
return-1;
}

test.c文件

在插入菜单前,main函数中调用的测试函数可以根据需要进行修改。

#define _CRT_SECURE_NO_WARNINGS 1#include "SeqList.h"voidTestSeqList1()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPushBack(&sl, 5);
SLPushBack(&sl, 5);
SLPushBack(&sl, 5);
SLPushBack(&sl, 5);
SLPushBack(&sl, 5);//插入了9个数据,扩了两次容SLPrint(&sl);
SLDestroy(&sl);
}
voidTestSeqList2()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPrint(&sl);
SLPopBack(&sl);
SLPrint(&sl);
SLPopBack(&sl);
SLPrint(&sl);
SLPopBack(&sl);
SLPopBack(&sl);
SLPopBack(&sl);
SLPopBack(&sl);
//SLPopBack(&sl);//越界调试,size--会导致size出现负数,后面如果再尾插,插入到了不属于自己的空间,就是越界访问SLPrint(&sl);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLDestroy(&sl);//去掉不报错}
voidTestSeqList3()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushFront(&sl, 1);
SLPushFront(&sl, 2);
SLPushFront(&sl, 3);
SLPushFront(&sl, 4);
SLPrint(&sl);
SLPopFront(&sl);
SLPopFront(&sl);
SLPopFront(&sl);
SLPopFront(&sl);
SLPopFront(&sl);//四个数据删除五次size为空,运行正常,可能没测试到位SLPushBack(&sl, 10);//这时就出现了问题,发生了越界,free会报错SLPrint(&sl);
SLDestroy(&sl);
}
voidTestSeqList4()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPrint(&sl);
SLInsert(&sl, 2, 20);//第二个位置插入20SLPrint(&sl);
SLInsert(&sl, 5, 500);//相当于尾插,需要考虑复用SLPrint(&sl);
SLInsert(&sl, 0, 100);//相当于头插,需要考虑复用SLPrint(&sl);
SLDestroy(&sl);
}
voidTestSeqList5()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPrint(&sl);
SLErase(&sl, 2);//删除下标为2的值SLPrint(&sl);
SLErase(&sl, 2);//删除下标为2的值SLPrint(&sl);
SLErase(&sl, 0);//删除下标为2的值SLPrint(&sl);
SLDestroy(&sl);
}
voidTestSeqList6()
{
SLsl;//定义顺序表的结构SLInit(&sl);//初始化,传给了SeqList.c中的函数,实参,传给形参,形参是实参的临时拷贝SLPushBack(&sl, 1);
SLPushBack(&sl, 2);
SLPushBack(&sl, 3);
SLPushBack(&sl, 4);
SLPushBack(&sl, 5);
SLPushBack(&sl, 7);
SLPushBack(&sl, 8);
SLPushBack(&sl, 5);
SLPrint(&sl);
/*int pos = SLFind(&sl, 5);if (pos != -1){SLErase(&sl, pos);}SLPrint(&sl);*/intpos=SLFind(&sl, 4,0);//从0开始查找if (pos!=-1)
    {
SLErase(&sl, pos);
    }
SLPrint(&sl);
//删除所有的5pos=SLFind(&sl, 5, 0);
while (pos!=-1)
    {
SLErase(&sl, pos);
pos=SLFind(&sl, 5, pos);//从删除5的位置继续往后找    }
SLPrint(&sl);
SLDestroy(&sl);
}
//int main()//{//  //TestSeqList1();//  //TestSeqList2();//  //TestSeqList3();//  //TestSeqList4();//  //TestSeqList5();//  TestSeqList6();////  //int* p1 = malloc(4);//  //int* p2 = realloc(p1, 20);//  //int* p3 = realloc(p2, 2000);//realloc原地扩容和异地扩容的演示////  ////越界读基本不会被检查出来//  //int a[10] = { 0 };//  //printf("%d\n", a[10]);//  //printf("%d\n", a[11]);//  ////  ////越界写,可能会被检查出来//  ////a[10] = 0;//检查出来//  //a[11] = 0;//未检查出来//  //////  return 0;//}//菜单voidmenu()
{
printf("********************************************\n");
printf("1、尾插数据 2、尾删数据\n");
printf("3、头插数据 2、头删数据\n");
printf("5、打印数据 -1、退出\n");
printf("********************************************\n");
}
intmain()
{
SLs;//定义顺序表SLInit(&s);//初始化intval=0;
intoption=0;
do    {
menu();
printf("请输入你的操作:>");
scanf("%d", &option);
switch (option)
        {
case1:
printf("请依次输入你要尾插的数据,以-1结束");
scanf("%d", &val);
while (val!=-1)
            {
SLPushBack(&s, val);
scanf("%d", &val);
            }
break;
case2:
SLPopFront(&s);
break;
case3:
break;
case4:
break;
case5:
SLPrint(&s);
break;
default:
break;
        }
    }while (option!=-1);
SLDestroy(&s);
return0;
}


结语:

这里本章内容就介绍完了, 希望以上内容对大家有所帮助👀,如有不足望指出🙏

前路漫漫!努力变强💪💪 吧!!

相关文章
|
10天前
|
存储 C语言
【C语言】C语言-学生选修课程系统(源码)【独一无二】
【C语言】C语言-学生选修课程系统(源码)【独一无二】
|
9天前
|
存储 数据可视化 C语言
【C语言】C语言 学生成绩管理系统(源码+报告)【千行代码】【独一无二】
【C语言】C语言 学生成绩管理系统(源码+报告)【千行代码】【独一无二】
|
9天前
|
存储 C语言
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
【C语言】C语言-宾馆客房管理系统(源码+论文)【独一无二】
|
11天前
|
存储 C语言
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
【C语言】C语言-学生成绩管理系统(源码+数据文件+课程论文)【独一无二】
25 15
|
1天前
|
算法 编译器 C语言
【C语言篇】猜数字游戏(赋源码)
rand函数会返回⼀个伪随机数,这个随机数的范围是在0~RAND_MAX之间,这个RAND_MAX的⼤⼩是依赖编译器上实现的,但是⼤部分编译器上是32767。
|
8天前
|
存储 数据可视化 数据安全/隐私保护
【C语言】C语言-成绩管理系统(管理员+教师+学生 源码)【独一无二】
【C语言】C语言-成绩管理系统(管理员+教师+学生 源码)【独一无二】
|
8天前
|
存储 数据可视化 C语言
【C语言】C语言-身份证管理系统(源码+注释)【独一无二】
【C语言】C语言-身份证管理系统(源码+注释)【独一无二】
|
9天前
|
存储 数据可视化 C语言
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】
【C语言】C语言-学生籍贯信息记录系统(源码+论文)【独一无二】
|
10天前
|
存储 C语言
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
【C语言】C语言-设备管理系统(源码+数据文件)【独一无二】
|
8天前
|
存储 数据可视化 Serverless
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】
【C语言】C语言-学籍管理系统(源码+文件存储)【独一无二】