静态链表结构
- 静态链表的结构实际上就是一个数组,静态链表的数组中,每一个元素代表一个结点,结点同样和链表一样包括数据域和指针域
- 只是在静态链表中的指针域不再是指针指向下一个结点的地址,而是用于存储下一个结点的数组下标,这样同样可以实现结点之间的连接关系
图示
在静态链表中
#define MaxSize 10 //最大链表长度
typedef char DataType;
typedef struct LNode
{
DataType data; //数据域
int next; //指针域
}StaticList;
void InitList(StaticList **L)
{
// 为静态链表分配空间
(*L) = (StaticList *)malloc(MaxSize * sizeof(StaticList));
// 初始化头结点
StaticList *s = *L;
s[0].data = '\0';
s[0].next = -1;
// 初始化链表
int i;
for (i = 1; i < MaxSize; i++)
{
s[i].data = '\0';
s[i].next = -2;
}
printf("已初始化链表\n");
}
头部插入
void HeadInsert(StaticList *L)
{
if (L)
{
DataType x;
printf("请输入插入的数据:");
fflush(stdin);
scanf("%c", &x);
// 获取新结点的下标位置
int free_node = GetFreeNodeIndex(L);
if (free_node > 0)
{
// 设置新结点的数据
L[free_node].data = x;
// 新结点指向链表的第一个结点
L[free_node].next = L[0].next;
// 头结点指向新结点,使得新结点成为链表的第一个结点
L[0].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 链表空间已满!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
尾部插入
void TailInsert(StaticList *L)
{
if (L)
{
int i;
DataType x;
printf("请输入插入的数据:");
fflush(stdin);
scanf("%c", &x);
int free_node = GetFreeNodeIndex(L);
if (free_node > 0)
{
int tail_index = 0;
// 查找尾结点下标
while (L[tail_index].next > 0)
{
tail_index = L[tail_index].next;
}
// 设置新结点数据
L[free_node].data = x;
// 新结点指针域设置为空
L[free_node].next = -1;
//尾结点指向新结点,使得新结点成为链表的最后一个结点
L[tail_index].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 链表空间已满\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
按位置插入
void LocateInsert(StaticList *L)
{
if (L)
{
int i, k;
DataType x;
printf("请输入插入的数据和插入位置:");
scanf("%d %c", &k, &x);
int free_node = GetFreeNodeIndex(L);
if (k > 0 && free_node > 0)
{
int insert_index = 0;
// 查找链表中第(k-1)个结点
while((--k) && L[insert_index].next > 0)
{
insert_index = L[insert_index].next;
}
// 插入新结点
if (k == 0)
{
// 设置新结点数据
L[free_node].data = x;
// 新结点指向第k个结点下标
L[free_node].next = L[insert_index].next;
// 第(k-1)个结点指向新结点
L[insert_index].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 插入位置不合法!\n");
}
}
else
{
printf("插入失败! 插入位置不合法/链表空间已满!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
头部删除
void HeadDelete(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int first_index;
// 获取第一个结点
first_index = L[0].next;
// 头结点指向第二个结点
L[0].next = L[first_index].next;
// 初始化第一个结点
L[first_index].data = '\0';
L[first_index].next = -2;
printf("删除成功!\n");
}
else
{
printf("删除失败! 链表为空!\n");
}
}
else
{
printf("删除失败! 链表已销毁!\n");
}
}
尾部删除
// 尾部删除
void TailDelete(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int i = 0, j = 0;
// 查询倒数第一个结点(i)和倒数第二个结点(j)
while (L[i].next > 0)
{
j = i;
i = L[i].next;
}
// 倒数第二个结点指向-1
L[j].next = -1;
// 初始化最后一个结点
L[i].data = '\0';
L[i].next = -2;
printf("删除成功!\n");
}
else
{
printf("插入失败! 链表为空!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
按位置删除
// 按位置删除
void LocateDelete(StaticList *L)
{
if (L)
{
int k;
printf("请输入删除的数据位置:");
scanf("%d", &k);
if (k > 0 && L[0].next > 0)
{
int i = 0, j = 0;
// 查询第(j = k-1)个结点和第(i = k)个结点
while ((k--) && L[i].next > 0)
{
j = i;
i = L[i].next;
}
if (k < 0)
{
// 第(k-1)个结点指向第(k+1)个结点
L[j].next = L[i].next;
// 初始化第k个结点
L[i].data = '\0';
L[i].next = -2;
printf("删除成功!\n");
}
else
{
printf("删除失败! 删除位置不合法!\n");
}
}
else
{
printf("删除失败! 链表为空!\n");
}
}
else
{
printf("删除失败! 链表已销毁!\n");
}
}
// 修改链表
void ListModify(StaticList *L)
{
if (L)
{
int k;
DataType x;
printf("请输入需要修改的位置和修改后的数据:");
scanf("%d %c", &k, &x);
if (k > 0)
{
int index = 0;
// 查询第i个结点位置
while ((k--) && L[index].next > 0)
{
index = L[index].next;
}
if (k < 0)
{
L[index].data = x;
printf("修改成功!\n");
}
else
{
printf("修改失败! 修改位置不合法!\n");
}
}
else
{
printf("修改失败! 修改位置不合法!\n");
}
}
else
{
printf("链表已销毁!\n");
}
}
#include
#include
#define MaxSize 10
typedef char DataType;
typedef struct LNode
{
DataType data;
int next;
}StaticList;
void InitList(StaticList **L)
{
// 为静态链表分配空间
(*L) = (StaticList *)malloc(MaxSize * sizeof(StaticList));
// 初始化
StaticList *s = *L;
s[0].data = '\0';
s[0].next = -1;
int i;
for (i = 1; i < MaxSize; i++)
{
s[i].data = '\0';
s[i].next = -2;
}
printf("已初始化链表\n");
}
// 查找空闲结点位置的下标
int GetFreeNodeIndex(StaticList *L)
{
int i;
for (i = 1; i < MaxSize; i++)
{
if (L[i].next == -2)
{
return i;
}
}
return 0;
}
// 头部插入
void HeadInsert(StaticList *L)
{
if (L)
{
DataType x;
printf("请输入插入的数据:");
fflush(stdin);
scanf("%c", &x);
// 获取新结点的下标位置
int free_node = GetFreeNodeIndex(L);
if (free_node > 0)
{
// 设置新结点的数据
L[free_node].data = x;
// 新结点指向链表的第一个结点
L[free_node].next = L[0].next;
// 头结点指向新结点,使得新结点成为链表的第一个结点
L[0].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 链表空间已满!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
// 尾部插入
void TailInsert(StaticList *L)
{
if (L)
{
int i;
DataType x;
printf("请输入插入的数据:");
fflush(stdin);
scanf("%c", &x);
int free_node = GetFreeNodeIndex(L);
if (free_node > 0)
{
int tail_index = 0;
// 查找尾结点下标
while (L[tail_index].next > 0)
{
tail_index = L[tail_index].next;
}
// 设置新结点数据
L[free_node].data = x;
// 新结点指针域设置为空
L[free_node].next = -1;
//尾结点指向新结点,使得新结点成为链表的最后一个结点
L[tail_index].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 链表空间已满\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
// 按位置插入
void LocateInsert(StaticList *L)
{
if (L)
{
int i, k;
DataType x;
printf("请输入插入的数据和插入位置:");
scanf("%d %c", &k, &x);
int free_node = GetFreeNodeIndex(L);
if (k > 0 && free_node > 0)
{
int insert_index = 0;
// 查找链表中第(k-1)个结点
while((--k) && L[insert_index].next > 0)
{
insert_index = L[insert_index].next;
}
// 插入新结点
if (k == 0)
{
// 设置新结点数据
L[free_node].data = x;
// 新结点指向第k个结点下标
L[free_node].next = L[insert_index].next;
// 第(k-1)个结点指向新结点
L[insert_index].next = free_node;
printf("插入成功!\n");
}
else
{
printf("插入失败! 插入位置不合法!\n");
}
}
else
{
printf("插入失败! 插入位置不合法/链表空间已满!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
// 头部删除
void HeadDelete(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int first_index;
// 获取第一个结点
first_index = L[0].next;
// 头结点指向第二个结点
L[0].next = L[first_index].next;
// 初始化第一个结点
L[first_index].data = '\0';
L[first_index].next = -2;
printf("删除成功!\n");
}
else
{
printf("删除失败! 链表为空!\n");
}
}
else
{
printf("删除失败! 链表已销毁!\n");
}
}
// 尾部删除
void TailDelete(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int i = 0, j = 0;
// 查询倒数第一个结点(i)和倒数第二个结点(j)
while (L[i].next > 0)
{
j = i;
i = L[i].next;
}
// 倒数第二个结点指向-1
L[j].next = -1;
// 初始化最后一个结点
L[i].data = '\0';
L[i].next = -2;
printf("删除成功!\n");
}
else
{
printf("插入失败! 链表为空!\n");
}
}
else
{
printf("插入失败! 链表已销毁!\n");
}
}
// 按位置删除
void LocateDelete(StaticList *L)
{
if (L)
{
int k;
printf("请输入删除的数据位置:");
scanf("%d", &k);
if (k > 0 && L[0].next > 0)
{
int i = 0, j = 0;
// 查询第(j = k-1)个结点和第(i = k)个结点
while ((k--) && L[i].next > 0)
{
j = i;
i = L[i].next;
}
if (k < 0)
{
// 第(k-1)个结点指向第(k+1)个结点
L[j].next = L[i].next;
// 初始化第k个结点
L[i].data = '\0';
L[i].next = -2;
printf("删除成功!\n");
}
else
{
printf("删除失败! 删除位置不合法!\n");
}
}
else
{
printf("删除失败! 链表为空!\n");
}
}
else
{
printf("删除失败! 链表已销毁!\n");
}
}
// 修改链表
void ListModify(StaticList *L)
{
if (L)
{
int k;
DataType x;
printf("请输入需要修改的位置和修改后的数据:");
scanf("%d %c", &k, &x);
if (k > 0)
{
int index = 0;
// 查询第i个结点位置
while ((k--) && L[index].next > 0)
{
index = L[index].next;
}
if (k < 0)
{
L[index].data = x;
printf("修改成功!\n");
}
else
{
printf("修改失败! 修改位置不合法!\n");
}
}
else
{
printf("修改失败! 修改位置不合法!\n");
}
}
else
{
printf("链表已销毁!\n");
}
}
// 遍历链表
void DisplayList(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int index = L[0].next;
while(index > 0)
{
printf("%c->", L[index].data);
index = L[index].next;
}
printf("null\n");
}
else
{
printf("链表为空!\n");
}
}
else
{
printf("遍历失败! 链表已销毁!\n");
}
}
// 求链表长度
void ListLength(StaticList *L)
{
if (L)
{
int index = 0, length = 0;
while (L[index].next > 0)
{
length++;
index = L[index].next;
}
printf("链表长度length = %d\n", length);
}
else
{
printf("链表已销毁!\n");
}
}
// 判断链表是否为空
void ListEmpty(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
printf("链表非空!\n");
}
else
{
printf("链表为空!\n");
}
}
else
{
printf("链表已销毁!\n");
}
}
// 清空链表
void ClearList(StaticList *L)
{
if (L)
{
if (L[0].next > 0)
{
int i = L[0].next, j = L[0].next;
// 依次清除结点
while (i > 0)
{
// j:用于暂存下一个结点
j = L[i].next;
// 初始化结点i
L[i].next = -2;
// i:移动到下一个结点
i = j;
}
L[0].next = -1;
printf("链表已清空!\n");
}
else
{
printf("链表为空!\n");
}
}
else
{
printf("链表已销毁!\n");
}
}
// 销毁链表
void DestroyList(StaticList **L)
{
free(*L);
(*L) = NULL;
printf("链表已销毁!\n");
}
// 打印静态链表数组
void DisplayArr(StaticList *L)
{
if (L)
{
int i;
printf("***************************\n");
printf("下标:\t");
for (i = 0; i < MaxSize; i++)
{
printf("%d\t", i);
}
printf("\n数据域:\t");
for (i = 0; i < MaxSize; i++)
{
if (L[i].data)
{
printf("%c\t", L[i].data);
}
else
{
printf("-\t");
}
}
printf("\n指针域:\t");
for (i = 0; i < MaxSize; i++)
{
printf("%d\t", L[i].next);
}
printf("\n***************************\n");
}
else
{
printf("链表已销毁!\n");
}
}
int main()
{
printf("*********************************\n");
printf("其他 | 0:退出\t1:初始化\n");
printf("插入 | 2:头插\t3:尾插\t4:按位插\n");
printf("删除 | 5:头删\t6:尾删\t7:按位删\n");
printf("查询 | 8:修改\t9:遍历\t10:求表长\n");
printf("其他 | 11:表空\t12:清空\t13:销毁\n");
printf("测试 | 14:打印静态链表数组\n");
printf("*********************************\n");
int k;
StaticList *L;
InitList(&L);
while (1)
{
printf("请输入操作序号:");
scanf("%d", &k);
if (!k)
{
break;
}
switch (k)
{
case 1:InitList(&L); break;
// 插入
case 2:HeadInsert(L); break;
case 3:TailInsert(L); break;
case 4:LocateInsert(L); break;
// 删除
case 5:HeadDelete(L); break;
case 6:TailDelete(L); break;
case 7:LocateDelete(L); break;
// 查询
case 8:ListModify(L); break;
case 9:DisplayList(L); break;
case 10:ListLength(L); break;
// 其他
case 11:ListEmpty(L); break;
case 12:ClearList(L); break;
case 13:DestroyList(&L);break;
case 14:DisplayArr(L); break;
default:break;
}
printf("\n");
}
system("pause");
return 0;
}