#include <stdio.h>
#include <stdlib.h>
//定义一个结构体
typedef struct book
{
int num;
char name[10];
struct book* next; //创建一个 存下一个地址的地址
}book;
//创建一个可以创建结点的链表函数
book* in()
{
book* head = NULL, * pnew;//创建一个 头节点地址和新节点地址;
book* end = pnew = (book*)malloc(sizeof(book));//创建要给个尾结点地址的同时给 新节点地址和尾结点地址一个和结构体一样的空间;
if (end == NULL && pnew == NULL) //判断 end 和 pnew 指针是否为空,是的话报错;
{
printf("erro NULL");
return 0;
}
printf("\n输入书的编号 和 书名\n");
scanf("%i%s", &pnew->num, &pnew->name);
int count = 0; //结点增减 循环判断;
while (pnew->num != 0) //如果输入的不是0,那就继续增加新节点;
{
count++; // 结点 增减循环判断;
if (count == 1) //循环判断如果为1 就变成头节点,如果超过1 就是新增节点;
{
pnew->next = head; //新结点地址的下一个地址存NULL;为了做循环判断是否为最后结点。
head = pnew; //新节点地址存入头节点地址,以后由头节点地址存的地址开始做循环;
end = pnew; //尾结点地址存入新节点地址,为了操作这个新地址的下一个地址存入下下一个结点的地址。
}
else
{
pnew->next = NULL;// 新增加结点的下一个地址为NULL;
end->next = pnew; // 之前的结点地址的下一个地址是NULL,将它改为这次新增的新节点地址;
end = pnew; // 尾结点地址指向这次新增的地址,为了下一次循环可以再次操作更改这个结点的下一个地址;
}
printf("\n是否接续增加新编号,新书名?\n");
pnew = (book*)malloc(sizeof(book));//为要再新增的结点创造一个空间,这个空间地址由 堆 里面提取;
if (pnew == NULL) //判断 end 和 pnew 指针是否为空,是的话报错;
{
printf("erro NULL");
return 0;
}
scanf("%i%s", &pnew->num, &pnew->name);
}
// 如果输入为 0 则不在增加。不在增加就跳出循环
free(pnew);//释放掉多余的空间
return head; //返回为头节点;
}
// 创建一个输出函数
void print(book* print)
{
while (print != NULL) //如果实参的下一个节点存的不是NULL,则一直输出所有结点。
{
printf("\n编号和书名为:\n编号NO:%i 书名《%s》\n------------------------------\n", print->num, print->name);
print = print->next; //创建一个判断,判断每个结点的next是不是指向NULL;
}
}
//创建一个优先显示的头结点函数;
book* addhead(book* addhead)
{
book* pnew = (book*)malloc(sizeof(book));
if (pnew == NULL) //判断 end 和 pnew 指针是否为空,是的话报错;
{
printf("erro NULL");
return 0;
}
printf("\n输入优先显示的编号和书名\n");
scanf("%i%s", &pnew->num, &pnew->name);
pnew->next = addhead; //新节点地址的下一个地址存入之前头结点地址;
addhead = pnew; //新结点地址变为头节点;
return addhead;
}
//创建一个结点删除函数
void delet(book* delet, int num)
{
book* temp, * remove; //创建一个临时存放地址和要删除结点地址的地址;
remove = temp = delet; //先把实参地址放入地址;
for (int i = 1; i < num; i++) //循环从第2开始,因为头地址已经算一个了。
{
temp = remove; //判断后 实参放入的地址放入临时地址;
remove = remove->next; //实参循环到指定的位置后 停止;
}
temp->next = remove->next; //要删除的结点地址的下一个地址放入在要被删除的前地址里的下一个地址里,使其相连;
free(remove); //然后释放掉不要的结点地址;
}
//主函数
int main()
{
int choose = 0;
book* linklist = in();
print(linklist); //输出链表结果
printf("是否增加一个优先显示? 是选 1 否输入其它按键\n");
scanf("%i", &choose);
if (choose == 1)
{
linklist = addhead(linklist); //添加头节点
print(linklist); //输出添加头节点后的链表
}
printf("是否删除一个结点? 是选 1 否输入其它按键\n");
scanf("%i", &choose);
if (choose == 1)
{
printf("删除第几个?\n");
scanf("%i", &choose);
delet(linklist, choose);
print(linklist);
}
return 0;
}
