前几节介绍的动态链表都是用C中堆内存的开辟方法,用函数malloc,free来开辟和释放节点,但是在某些语言中没有指针的类型,如何做呢?可以用数组来模拟动态链表的创建过程。
/************************************************************************/
/* @author lynnbest
目标:静态链表的使用 插入和删除
1.创建一个静态循环链表 {A,B,C,D,E,F}
2.插入操作
3.删除操作
4.打印操作 */
/************************************************************************/
/************************************************************************/
/* 思路:
用数组来模拟动态链表的创建过程
1.插入
①先获取备份空闲节点 L.av 同时更新新节点数据和av
②遍历获取位置 得到前驱节点
③插入
*/
/************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define size 10
typedef struct //节点结构体
{
char data; //数据域
int cur; //游标指针
}slistnode;
typedef struct
{
slistnode list[size]; //数组个数
int av; //备份游标指针
}slinklist;
void InitSlinklist(slinklist *L);
void InsertSlistNode(slinklist *L,int pos,char ch);
void DeleteSlistNode(slinklist *L,int pos);
void PrintfSlist(slinklist L);
int length(slinklist L);
void main()
{
printf(" 静态链表的使用 \n");
printf("----by lynnbest ----\n\n");
//初始化链表
slinklist L;
InitSlinklist(&L); //初始化静态链表,m.
int choice,pos;
char ch;
while(1)
{
printf("1---创建静态链表\n");
printf("2---插入节点\n");
printf("3---删除节点表\n");
printf("4---打印当前元素\n");
printf("5---退出\n请选择:\n");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
char a[]={'A','B','C','D','E'};
int len=sizeof(a)/sizeof(a[0]);
for(int j=1;j<=len;j++)
InsertSlistNode(&L,j,a[j-1]);
break;
}
case 2:
{
printf("请输入要插入的元素位置和字符:\n");
scanf("%d,%c",&pos,&ch);
// printf("请输入要插入的位置:\n");
// scanf("%d",&pos);
InsertSlistNode(&L,pos,ch);
break;
}
case 3:
{ printf("请输入要删除元素的位置:\n");
scanf("%d",&pos);
DeleteSlistNode(&L,pos);
break;
}
case 4:
{ printf("静态链表中的元素为:\n");
PrintfSlist(L);
break;
}
case 5:
{
return;
}
default :
break;
}
}
}
void InitSlinklist(slinklist *L)
{
memset(L,NULL,sizeof(*L));
for(int i=0;i<size;i++) //初始化cur i是数组编号
{
(*L).list[i].cur=i+1;
}
(*L).list[size-1].cur=0; //做循环
(*L).av=1; //分配空闲节点
}
void InsertSlistNode(slinklist *L,int pos,char ch)
{
if(pos<1||pos>size-1)
{
printf("插入位置非法\n");
return ;
}
int able=(*L).av; //获取空闲节点
(*L).list[able].data=ch; //插入新数据
(*L).av=(*L).list[able].cur; //更新空闲节点
//int start=(*L).list[0].cur; //开始位置
int start=0;
for(int i=0;i<pos-1;i++)
start=(*L).list[start].cur;
//遍历完后,查找到 start为前驱编号
(*L).list[able].cur=(*L).list[start].cur; //先修改able的指针
(*L).list[start].cur=able; //在修改前驱编号的指针
}
void DeleteSlistNode(slinklist *L,int pos)
{
if(pos<1||pos>size-1)
{
printf("删除位置非法\n");
return ;
}
// int pre=(*L).list[0].cur;
int pre=0;
for(int x=0;x<pos-1;x++)
pre=(*L).list[pre].cur; //查找删除节点的前驱编号
int next=(*L).list[pre].cur; //获取下一个游标
(*L).list[pre].cur=(*L).list[next].cur; //删除操作结束
(*L).list[next].cur=(*L).av;
(*L).av=next;
}
void PrintfSlist(slinklist L)
{
int start=L.list[0].cur;
for(int i=1;i<=length(L);i++)
{
printf("%3c",L.list[start].data);
start=L.list[start].cur;
}
printf("\n");
}
int length(slinklist L)
{
int p=L.list[0].cur;
int count=0;
while( L.list[p].cur!=1)//还不完善
{ p=L.list[p].cur;
count++;
}
return count+1;
}