文章目录 简介 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中的宏定义来控制的。