文章目录
简介 1.头插功能 2.头删功能 3.尾插功能 4.尾删功能 5.此程序共包含4个文件,2个.c文件和2个.h文件 5.1 SeqList.h文件 5.2 SeqList.c文件 5.3 test.h文件 5.4 test.c文件
6.测试结果 6.1 测试尾插和尾删的运行结果 6.2 测试头插和头删的运行结果
7.温馨提示
简介
本文主要介绍顺序表的头插、头删、尾插、尾删,提供全部的.c和.h文件,确保使用者直接复制粘贴到编译器上即可直接运行程序。
1.头插功能
思路是先找到数组的最后一个元素,然后把元素一个一个都往后挪一位。最后将要插入的数据x放在数组的头的位置。
void SeqListPushFront ( SL* ps, SLDataType x)
{
SeqListCheckCapacity ( ps) ;
int end = ps-> size - 1 ;
while ( end >= 0 )
{
ps-> a[ end + 1 ] = ps-> a[ end] ;
end-- ;
}
ps-> a[ 0 ] = x;
ps-> size++ ;
return ;
}
检查是否扩容,是在插入元素时,检查数据个数是否超过了最大容量或者是否需要开辟空间,如果是需要进行空间的开辟或扩容。
void SeqListCheckCapacity ( SL* ps)
{
if ( ps-> capacity == ps-> size)
{
int newCapacity = ( ps-> capacity == 0 ) ? 4 : ps-> capacity * 2 ;
SLDataType* temp = ( SLDataType* ) realloc ( ps-> a, newCapacity * sizeof ( SLDataType) ) ;
if ( NULL == temp)
{
printf ( "realloc fail!\n" ) ;
exit ( - 1 ) ;
}
ps-> a = temp;
ps-> capacity = newCapacity;
}
return ;
}
2.头删功能
思路是先找到数组的第2个元素,然后从第2个数据开始,每个数据往前挪动一位进行数据覆盖。
void SeqListPopFront ( SL* ps)
{
assert ( ps-> size > 0 ) ;
int begin = 1 ;
while ( begin < ps-> size)
{
ps-> a[ begin - 1 ] = ps-> a[ begin] ;
begin++ ;
}
ps-> size-- ;
return ;
}
3.尾插功能
思路是先检查是否需要扩容,然后将需要插入的数据x直接放到数组的尾部即可。
void SeqListPushBack ( SL * ps, SLDataType x)
{
SeqListCheckCapacity ( ps) ;
ps-> a[ ps-> size] = x;
ps-> size++ ;
return ;
}
4.尾删功能
思路是直接减1有效数据的个数,以此达到删除数组中最后一个元素的目的。
void SeqListPopBack ( SL* ps)
{
assert ( ps-> size > 0 ) ;
ps-> size-- ;
return ;
}
5.此程序共包含4个文件,2个.c文件和2个.h文件
5.1 SeqList.h文件
文件中包含了函数功能的头文件以及对应的结构体。
# pragma once
# include <stdio.h>
# include <stdlib.h>
typedef int SLDataType;
typedef struct SeqList
{
SLDataType* a;
int size;
int capacity;
} SL;
void SeqListInit ( SL * ps) ;
void SeqListPushBack ( SL * ps, SLDataType x) ;
void SeqListPopBack ( SL * ps) ;
void SeqListPushFront ( SL * ps, SLDataType x) ;
void SeqListPopFront ( SL * ps) ;
void SeqListCheckCapacity ( SL* ps) ;
void SeqListFree ( SL * ps) ;
void SeqListPrint ( SL * ps) ;
5.2 SeqList.c文件
文件中包含了功能函数的具体实现方式。
# define _CRT_SECURE_NO_WARNINGS
# include "SeqList.h"
# include <assert.h>
void SeqListInit ( SL * ps)
{
ps-> a = NULL ;
ps-> size = ps-> capacity = 0 ;
if ( ( NULL == ps-> a) && ( 0 == ps-> size) && ( 0 == ps-> capacity) )
{
printf ( "Init Success!\n" ) ;
}
else
{
printf ( "Init Fail!\n" ) ;
}
return ;
}
void SeqListPushBack ( SL * ps, SLDataType x)
{
SeqListCheckCapacity ( ps) ;
ps-> a[ ps-> size] = x;
ps-> size++ ;
return ;
}
void SeqListPopBack ( SL* ps)
{
assert ( ps-> size > 0 ) ;
ps-> size-- ;
return ;
}
void SeqListPushFront ( SL* ps, SLDataType x)
{
SeqListCheckCapacity ( ps) ;
int end = ps-> size - 1 ;
while ( end >= 0 )
{
ps-> a[ end + 1 ] = ps-> a[ end] ;
end-- ;
}
ps-> a[ 0 ] = x;
ps-> size++ ;
return ;
}
void SeqListPopFront ( SL* ps)
{
assert ( ps-> size > 0 ) ;
int begin = 1 ;
while ( begin < ps-> size)
{
ps-> a[ begin - 1 ] = ps-> a[ begin] ;
begin++ ;
}
ps-> size-- ;
return ;
}
void SeqListCheckCapacity ( SL* ps)
{
if ( ps-> capacity == ps-> size)
{
int newCapacity = ( ps-> capacity == 0 ) ? 4 : ps-> capacity * 2 ;
SLDataType* temp = ( SLDataType* ) realloc ( ps-> a, newCapacity * sizeof ( SLDataType) ) ;
if ( NULL == temp)
{
printf ( "realloc fail!\n" ) ;
exit ( - 1 ) ;
}
ps-> a = temp;
ps-> capacity = newCapacity;
}
return ;
}
void SeqListFree ( SL* ps)
{
free ( ps-> a) ;
ps-> a = NULL ;
ps-> capacity = ps-> size = 0 ;
return ;
}
void SeqListPrint ( SL* ps)
{
assert ( ps != NULL ) ;
int i = 0 ;
for ( i = 0 ; i < ( ps-> size) ; i++ )
{
printf ( "a[%d] = %d\n" , i, ps-> a[ i] ) ;
}
printf ( "\n" ) ;
return ;
}
5.3 test.h文件
文件中定义了控制宏的开关,用来测试时方便的控制插入和删除的个数。
# pragma once
# define SEQ_LIST_PUSH_BACK_NUM 5
# define SEQ_LIST_POP_BACK_NUM 3
# define SEQ_LIST_PUSH_FRONT_NUM 15
# define SEQ_LIST_POP_FRONT_NUM 3
5.4 test.c文件
用来进行相应功能的测试,TestSeqList1()和TestSeqList2(),分别测试尾插、尾删和头插、头删。使用者可以自己控制注释,来测试不同的功能。
# define _CRT_SECURE_NO_WARNINGS
# include "SeqList.h"
# include "test.h"
void TestSeqList1 ( )
{
SL s;
int i = 0 ;
SeqListInit ( & s) ;
for ( i = 0 ; i < SEQ_LIST_PUSH_BACK_NUM; i++ )
{
SeqListPushBack ( & s, i) ;
}
SeqListPrint ( & s) ;
for ( i = 0 ; i < SEQ_LIST_POP_BACK_NUM; i++ )
{
SeqListPopBack ( & s) ;
}
SeqListPrint ( & s) ;
SeqListFree ( & s) ;
return ;
}
void TestSeqList2 ( )
{
SL s;
int i = 0 ;
SeqListInit ( & s) ;
for ( i = 0 ; i < SEQ_LIST_PUSH_BACK_NUM; i++ )
{
SeqListPushBack ( & s, i) ;
}
SeqListPrint ( & s) ;
for ( i = 10 ; i < SEQ_LIST_PUSH_FRONT_NUM; i++ )
{
SeqListPushFront ( & s, i) ;
}
SeqListPrint ( & s) ;
for ( i = 0 ; i < SEQ_LIST_POP_FRONT_NUM; i++ )
{
SeqListPopFront ( & s) ;
}
SeqListPrint ( & s) ;
SeqListFree ( & s) ;
return ;
}
int main ( )
{
TestSeqList1 ( ) ;
return 0 ;
}
6.测试结果
6.1 测试尾插和尾删的运行结果
从运行结果可以看出,尾插函数插入了5个元素分别是0,1,2,3,4。执行过尾删后,删除了后边的3个元素。
6.2 测试头插和头删的运行结果
从运行结果可以看出,通过尾插先插入5个元素分别是0,1,2,3,4。
然后执行头插,插入了10,11,12,13,14这5个元素,最后执行了头删,删除了前边的3个元素。
7.温馨提示
插入和删除的个数,均是通过test.h中的宏定义来控制的。