基本概念
逻辑上来看,线性表由n(n>=0)个数据元素a1、a2、a3…an组成。 n为表的长度,也就是数据元素的个数。 表空时n=0 对于一个非空的线性表所具有的逻辑结构特征: 1、有且仅有一个开始节点a1,没有直接前驱节点,有且仅有一个直接后继节点。 2、有切仅有一个终结节点an,没有直接后继节点,有且仅有一个直接前驱节点。 3、其余的内部节点ai(2<= i <= n-1),有且仅有一个直接前驱节点和一个直接后继节点。 对于同意线性表,各个数据元素的数据类型都必须相同。
线性表的基本运算
void SLInit ( SLType * SL) {
SL-> listLen = 0 ;
printf ( "[*] 线性表初始化成功...\n" ) ;
}
计算表长度(ListLength) 计算线性表L中节点的个数
int SLLength ( SLType * SL) {
return SL-> listLen;
}
获取节点(GetNode) 取出线性表L中第i个节点的数据( 1 <= i <= ListLength(L) )
DATA * SLFindByNum ( SLType * SL, int n) {
if ( n< 1 || n> SL-> listLen) {
printf ( "序号错误,不能返回节点!\n" ) ;
return NULL ;
}
return & ( SL-> ListData[ n] ) ;
}
查找节点 (LocateNode) 在线性表L中查找值为x的节点,并返回节点在线性表中的位置。若没有找到则返回错误标志。若有多个重复的值,则只返回第一个相同的节点。
int SLFindByCont ( SLType * SL, char * name) {
int i;
for ( i= 1 ; i< SL-> listLen; i++ ) {
if ( strcmp ( SL-> ListData[ i] . name, name) == 0 ) {
return i;
}
}
return 0 ;
}
插入节点(InsertList) 在线性表L中的第i个位置上插入第一个新的节点,其后面节点的编号一次加1。每次添加一个节点,长度+1。
int SLadd ( SLType * SL, DATA data) {
if ( SL-> listLen >= MAXLENGTH) {
printf ( "顺序表已满,插入失败" ) ;
return 0 ;
}
SL-> ListData[ ++ SL-> listLen] = data;
return 1 ;
}
int SLInsert ( SLType * SL, int n, DATA data) {
int i;
if ( SL-> listLen >= MAXLENGTH) {
printf ( "顺序表已满,插入失败" ) ;
return 0 ;
}
if ( n< 1 || n> SL-> listLen- 1 ) {
printf ( "元素序号错误,插入失败" ) ;
return 0 ;
}
for ( i= SL-> listLen; i>= n; i-- ) {
SL-> ListData[ i+ 1 ] = SL-> ListData[ i] ;
}
SL-> ListData[ n] = data;
SL-> listLen ++ ;
return 1 ;
}
删除节点(DeleteList) 删除线性表L上第i个节点,使其后面的所有编号依次-1,删除后线性表的长度-1。
int SLDelete ( SLType * SL, int n) {
int i;
if ( n< 1 || n> SL-> listLen ) {
printf ( "节点序号错误,删除失败" ) ;
return 0 ;
}
for ( i= n; i< SL-> listLen; i++ ) {
SL-> ListData[ i] = SL-> ListData[ i+ 1 ] ;
}
SL-> listLen-- ;
return 1 ;
}
完整代码
# include "stdio.h"
# include "string.h"
# define MAXLENGTH 100
typedef struct {
char name[ 20 ] ;
int age;
} DATA;
typedef struct {
DATA ListData[ MAXLENGTH+ 1 ] ;
int listLen;
} SLType;
void SLInit ( SLType * SL) {
SL-> listLen = 0 ;
printf ( "[*] 线性表初始化成功...\n" ) ;
}
int SLLength ( SLType * SL) {
return SL-> listLen;
}
int SLInsert ( SLType * SL, int n, DATA data) {
int i;
if ( SL-> listLen >= MAXLENGTH) {
printf ( "顺序表已满,插入失败" ) ;
return 0 ;
}
if ( n< 1 || n> SL-> listLen- 1 ) {
printf ( "元素序号错误,插入失败" ) ;
return 0 ;
}
for ( i= SL-> listLen; i>= n; i-- ) {
SL-> ListData[ i+ 1 ] = SL-> ListData[ i] ;
}
SL-> ListData[ n] = data;
SL-> listLen ++ ;
return 1 ;
}
int SLadd ( SLType * SL, DATA data) {
if ( SL-> listLen >= MAXLENGTH) {
printf ( "顺序表已满,插入失败" ) ;
return 0 ;
}
SL-> ListData[ ++ SL-> listLen] = data;
return 1 ;
}
int SLDelete ( SLType * SL, int n) {
int i;
if ( n< 1 || n> SL-> listLen ) {
printf ( "节点序号错误,删除失败" ) ;
return 0 ;
}
for ( i= n; i< SL-> listLen; i++ ) {
SL-> ListData[ i] = SL-> ListData[ i+ 1 ] ;
}
SL-> listLen-- ;
return 1 ;
}
DATA * SLFindByNum ( SLType * SL, int n) {
if ( n< 1 || n> SL-> listLen) {
printf ( "序号错误,不能返回节点!\n" ) ;
return NULL ;
}
return & ( SL-> ListData[ n] ) ;
}
int SLFindByCont ( SLType * SL, char * name) {
int i;
for ( i= 1 ; i< SL-> listLen; i++ ) {
if ( strcmp ( SL-> ListData[ i] . name, name) == 0 ) {
return i;
}
}
return 0 ;
}
void SLshowAll ( SLType * SL) {
int i;
for ( i= 1 ; i<= SL-> listLen; i++ ) {
printf ( "(%s,%d)\n" , SL-> ListData[ i] . name, SL-> ListData[ i] . age) ;
}
}
void manu ( ) {
printf ( "=================================================\n" ) ;
printf ( " 1、插入节点 \n" ) ;
printf ( " 2、删除节点 \n" ) ;
printf ( " 3、通过序号查找节点 \n" ) ;
printf ( " 4、通过姓名查找节点 \n" ) ;
printf ( " 5、追加节点 \n" ) ;
printf ( " 6、打印所有节点 \n" ) ;
printf ( " 0、推出程序 \n" ) ;
printf ( "=================================================\n" ) ;
}
int main ( ) {
int opt;
int n;
SLType SL;
DATA data;
DATA * pdata;
char name[ 10 ] ;
fflush ( stdin ) ;
SLInit ( & SL) ;
printf ( "当前表长度:%d\n" , SLLength ( & SL) ) ;
do {
manu ( ) ;
printf ( "请输入操作" ) ;
scanf ( "%d" , & opt) ;
switch ( opt) {
case 1 :
fflush ( stdin ) ;
printf ( "插入位置:>" ) ;
scanf ( "%d" , & n) ;
printf ( "插入的数据(姓名,年龄)>" ) ;
scanf ( "%s,%d" , & data. name, & data. age) ;
SLInsert ( & SL, n, data) ;
printf ( "当前表长度:%d\n" , SLLength ( & SL) ) ;
break ;
case 2 :
fflush ( stdin ) ;
printf ( "删除的节点:>" ) ;
scanf ( "%d" , & n) ;
SLDelete ( & SL, n) ;
printf ( "当前表长度:%d\n" , SLLength ( & SL) ) ;
break ;
case 3 :
fflush ( stdin ) ;
printf ( "查找的节点序号:>" ) ;
scanf ( "%d" , & n) ;
pdata = SLFindByNum ( & SL, n) ;
printf ( "(%s,%d)\n" , pdata-> name, pdata-> age) ;
break ;
case 4 :
fflush ( stdin ) ;
printf ( "查找的姓名:>" ) ;
scanf ( "%s" , & name) ;
n = SLFindByCont ( & SL, name) ;
printf ( "查找的姓名在第%d个节点\n" , n) ;
break ;
case 5 :
fflush ( stdin ) ;
printf ( "插入的数据(姓名,年龄)>" ) ;
scanf ( "%s,%d" , & data. name, & data. age) ;
SLadd ( & SL, data) ;
printf ( "当前表长度:%d\n" , SLLength ( & SL) ) ;
break ;
case 6 :
SLshowAll ( & SL) ;
break ;
case 0 :
return 0 ;
default :
printf ( "请选择正确操作!\n" ) ;
}
} while ( 1 ) ;
}