本程序采用
严蔚敏数据结构C语言版的思想进行编写的程序
是书中没有的
静态链表的更改程序
由于是本人根据自己的思想理解单独敲出的,所以会有漏洞,仅供参考理解。
/*
本程序采用
严蔚敏数据结构C语言版的思想进行编写的程序
是书中没有的
静态链表的更改程序
由于是本人根据自己的思想理解单独敲出的,所以会有漏洞,仅供参考理解。
*/
//头文件
#include<stdio.h>
#include<stdlib.h>
//宏区
#define SIZEMAX 10 //定义静态链表的最大存储容量为10个结点
//结构
typedef struct //定义当前单个静态链表的结构
{
int data; //静态链表的数据域
int cur; //静态链表的游标域
}SQlink,Link_list[SIZEMAX]; //定义当前这个静态链表的定义名字
//函数声明
void Link_list_initialize(Link_list); //建立空表(初始化)
void Link_list_establish(Link_list); //静态链表的建立(包括分配备用结点)
int Link_list_allot(Link_list); //静态链表的分配空闲结点
void Link_list_change(Link_list); //静态链表的更改
void Link_list_printf(Link_list); //静态链表的输出
//函数区
void Link_list_initialize(Link_list link_list) //建立空表(初始化)——将所有结点挂在备用头结点上
{
int i;
for (i = 0;i < SIZEMAX;i++) //将所有结点挂在备用结点上
link_list[i].cur = i + 1; //依次指向下一个结点
link_list[SIZEMAX - 1].cur = NULL; //将备用结点的尾结点的游标挂起
}
void Link_list_establish(Link_list link_list) //静态链表的建立(包括分配备用结点)
{
int i, len, c, k, val;
printf("输入需要开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
while (len <= 0 || len > 8) //因为下标为0,1的分别是备用头结点合有效头结点。所以可分配的只有8个结点
{
printf("输入非法,重新选择开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
}
i = Link_list_allot(link_list); //静态链表的分配空闲结点
c = i; //该游标始终指向尾结点
for (k = 1;k <= len;k++) //依次开辟结点,建立静态链表
{
printf("输入第%d个静态链表结点的数据:", k); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
i = Link_list_allot(link_list); //分配空闲结点
link_list[i].data = val; //将数据存入新开辟的结点
link_list[c].cur = i; //将新开辟的结点被前一个的结点指向
c = i; //c始终指向尾结点
}
link_list[c].cur = NULL; //将有效结点的尾结点的游标域挂起
}
int Link_list_allot(Link_list link_list) //静态链表的分配空闲结点
{
int i;
if (link_list[0].cur) //判断是否还有空闲结点,如果有
{
i = link_list[0].cur; //用i指向背分配的结点
link_list[0].cur = link_list[i].cur; //将被分配的结点的下一个结点挂在备用头结点
}
else //如果没有空闲结点
{
printf("没有可以分配的空闲结点了,检查程序!\n"); //提醒用户
exit(0); //正常终止程序
}
return i; //返回背分配结点的下标
}
void Link_list_printf(Link_list link_list) //静态链表的输出
{
int i;
i = link_list[1].cur; //i指向第一个有效结点
printf("当前静态链表的数据为:"); //显示
while (i) //只要当前结点有数据
{
printf("%d ", link_list[i].data); //输出当前结点的数据
i = link_list[i].cur; //后移下一个结点
}
printf("\n"); //换行
}
void Link_list_change(Link_list link_list) //静态链表的更改
{
int whe, i = 1, j, c, val;
printf("输入你要更改值的位置:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &whe); //记录位置
printf("输入你要更改的数据:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
for (j = 1;j <= whe;j++)
i = link_list[i].cur; //第一次循环将i指向第一个有效结点,后面的循环即依次后移
link_list[i].data = val; //将用户需要更改的值赋给用户需要更改的结点
}
//主函数
int main(void)
{
Link_list link_list; //定义静态链表的头指针
Link_list_initialize(link_list); //静态链表的初始化(建立空表)
Link_list_establish(link_list); //静态链表的建立(包括分配备用结点)
Link_list_printf(link_list); //静态链表的输出
Link_list_change(link_list); //静态链表的更改
Link_list_printf(link_list); //静态链表的输出
return 0;
}
模块一:
定义静态链表的最大存储容量为10个结点(宏定义)
//宏区
#define SIZEMAX 10
模块二:
定义当前单个静态链表的结构
//结构
typedef struct //定义当前单个静态链表的结构
{
int data; //静态链表的数据域
int cur; //静态链表的游标域
}SQlink,Link_list[SIZEMAX]; //定义当前这个静态链表的定义名字
模块三:
建立空表(初始化)——将所有结点挂在备用头结点上
void Link_list_initialize(Link_list link_list) //建立空表(初始化)——将所有结点挂在备用头结点上
{
int i;
for (i = 0;i < SIZEMAX;i++) //将所有结点挂在备用结点上
link_list[i].cur = i + 1; //依次指向下一个结点
link_list[SIZEMAX - 1].cur = NULL; //将备用结点的尾结点的游标挂起
}
模块四:
静态链表建立
void Link_list_establish(Link_list link_list) //静态链表的建立(包括分配备用结点)
{
int i, len, c, k, val;
printf("输入需要开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
while (len <= 0 || len > 8) //因为下标为0,1的分别是备用头结点合有效头结点。所以可分配的只有8个结点
{
printf("输入非法,重新选择开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
}
i = Link_list_allot(link_list); //静态链表的分配空闲结点
c = i; //该游标始终指向尾结点
for (k = 1;k <= len;k++) //依次开辟结点,建立静态链表
{
printf("输入第%d个静态链表结点的数据:", k); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
i = Link_list_allot(link_list); //分配空闲结点
link_list[i].data = val; //将数据存入新开辟的结点
link_list[c].cur = i; //将新开辟的结点被前一个的结点指向
c = i; //c始终指向尾结点
}
link_list[c].cur = NULL; //将有效结点的尾结点的游标域挂起
}
模块五:
静态链表的分配空闲结点
int Link_list_allot(Link_list link_list) //静态链表的分配空闲结点
{
int i;
if (link_list[0].cur) //判断是否还有空闲结点,如果有
{
i = link_list[0].cur; //用i指向背分配的结点
link_list[0].cur = link_list[i].cur; //将被分配的结点的下一个结点挂在备用头结点
}
else //如果没有空闲结点
{
printf("没有可以分配的空闲结点了,检查程序!\n"); //提醒用户
exit(0); //正常终止程序
}
return i; //返回背分配结点的下标
}
模块六:
静态链表的输出
void Link_list_printf(Link_list link_list) //静态链表的输出
{
int i;
i = link_list[1].cur; //i指向第一个有效结点
printf("当前静态链表的数据为:"); //显示
while (i) //只要当前结点有数据
{
printf("%d ", link_list[i].data); //输出当前结点的数据
i = link_list[i].cur; //后移下一个结点
}
printf("\n"); //换行
}
模块七:
静态链表的更改
void Link_list_change(Link_list link_list) //静态链表的更改
{
int whe, i = 1, j, c, val;
printf("输入你要更改值的位置:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &whe); //记录位置
printf("输入你要更改的数据:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
for (j = 1;j <= whe;j++)
i = link_list[i].cur; //第一次循环将i指向第一个有效结点,后面的循环即依次后移
link_list[i].data = val; //将用户需要更改的值赋给用户需要更改的结点
}
模块八:
主函数
//主函数
int main(void)
{
Link_list link_list; //定义静态链表的头指针
Link_list_initialize(link_list); //静态链表的初始化(建立空表)
Link_list_establish(link_list); //静态链表的建立(包括分配备用结点)
Link_list_printf(link_list); //静态链表的输出
Link_list_change(link_list); //静态链表的更改
Link_list_printf(link_list); //静态链表的输出
return 0;
}
本程序的重点是静态链表的更改功能:
void Link_list_change(Link_list link_list) //静态链表的更改
{
int whe, i = 1, j, c, val;
printf("输入你要更改值的位置:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &whe); //记录位置
printf("输入你要更改的数据:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
for (j = 1;j <= whe;j++)
i = link_list[i].cur; //第一次循环将i指向第一个有效结点,后面的循环即依次后移
link_list[i].data = val; //将用户需要更改的值赋给用户需要更改的结点
}
需要说明的是,在头上定义了i = 1,方便后续循环的结点能与循环次数同步。
int whe, i = 1, j, c, val;
且可以看到:第一次循环将i指向第一个有效结点,后面的循环即依次后移
for (j = 1;j <= whe;j++)
i = link_list[i].cur; //第一次循环将i指向第一个有效结点,后面的循环即依次后移
/``````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````````/
新颖地方一:
有意思的是在用户建立的模块中
void Link_list_establish(Link_list link_list) //静态链表的建立(包括分配备用结点)
{
int i, len, c, k, val;
printf("输入需要开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
while (len <= 0 || len > 8) //因为下标为0,1的分别是备用头结点合有效头结点。所以可分配的只有8个结点
{
printf("输入非法,重新选择开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
}
i = Link_list_allot(link_list); //静态链表的分配空闲结点
c = i; //该游标始终指向尾结点
for (k = 1;k <= len;k++) //依次开辟结点,建立静态链表
{
printf("输入第%d个静态链表结点的数据:", k); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
i = Link_list_allot(link_list); //分配空闲结点
link_list[i].data = val; //将数据存入新开辟的结点
link_list[c].cur = i; //将新开辟的结点被前一个的结点指向
c = i; //c始终指向尾结点
}
link_list[c].cur = NULL; //将有效结点的尾结点的游标域挂起
}
对其用户输入的数据进行规定的限制:
while (len <= 0 || len > 8) //因为下标为0,1的分别是备用头结点合有效头结点。所以可分配的只有8个结点
{
printf("输入非法,重新选择开辟静态链表的结点个数:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &len); //记录个数
}
原因很简单:因为下标为0,1的分别是备用头结点合有效头结点。而在宏定义最大的容量为10,所以可分配的只有8个结点
新颖地方二:
在分配空闲结点的模块中
int Link_list_allot(Link_list link_list) //静态链表的分配空闲结点
{
int i;
if (link_list[0].cur) //判断是否还有空闲结点,如果有
{
i = link_list[0].cur; //用i指向背分配的结点
link_list[0].cur = link_list[i].cur; //将被分配的结点的下一个结点挂在备用头结点
}
else //如果没有空闲结点
{
printf("没有可以分配的空闲结点了,检查程序!\n"); //提醒用户
exit(0); //正常终止程序
}
return i; //返回背分配结点的下标
}
模块六:
可以看到
if (link_list[0].cur) //判断是否还有空闲结点,如果有
{
i = link_list[0].cur; //用i指向背分配的结点
link_list[0].cur = link_list[i].cur; //将被分配的结点的下一个结点挂在备用头结点
}
else //如果没有空闲结点
{
printf("没有可以分配的空闲结点了,检查程序!\n"); //提醒用户
exit(0); //正常终止程序
}
采用的if···else,if内的判断表达式是判断是否还有下一个空闲结点,如果没有则终止程序的运行,因为在建立的时候限制了输入的个数,所以一般不会触发。
最后本程序的核心程序模块再一次的作为结尾程序出现下吧:
静态链表的更改功能
void Link_list_change(Link_list link_list) //静态链表的更改
{
int whe, i = 1, j, c, val;
printf("输入你要更改值的位置:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &whe); //记录位置
printf("输入你要更改的数据:"); //显示用于提醒用户进行对应的操作
scanf_s("%d", &val); //记录数据
for (j = 1;j <= whe;j++)
i = link_list[i].cur; //第一次循环将i指向第一个有效结点,后面的循环即依次后移
link_list[i].data = val; //将用户需要更改的值赋给用户需要更改的结点
}
感谢观看
再次感谢~