基本概念
- 逻辑上来看,线性表由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);
}