一、单链表
链表是一种常见的基础数据结构。根据需求,我们可以构造出单链表、双链表、循环链表和块状链表等。链表的出现很大程度上弥补了数组的先天不足。
单链表包含两个域:信息域和指针域。
- 信息域用来存放链表节点的内容
- 指针域用来指向下一节点
单链表是用指针串联到一起的,直到指针指向NULL,表示单链表结束。
单链表节点的声明:需要添加一个指向自身的指针域。
举个栗子:
#include <stdio.h>
//单链表节点的声明
struct Book
{
char title[128];
char author[40];
struct Book *next;
};
int main(void)
{
return 0;
}
1.头插法
在单链表中插入元素(节点):首先,在堆中申请一个内存空间来存放节点,填充弄信息域,然后,通过调整指针指向来实现插入。
举个栗子:头插法
#include <stdio.h>
#include <stdlib.h>
//单链表节点的声明
struct Book
{
char title[128];
char author[40];
struct Book *next;
}
//填充信息域
void getInput(struct Book *book)
{
printf("请输入书名:");
scanf("%s",book->title);
printf("请输入作者:");
scanf("%s",book->author);
}
//这里**是因为library指针中存放的值是需要修改的,因此,要将指针的地址传进来,就是指向Book结构体指针的指针
void addBook(struct Book **library)
{
struct Book *book, *temp;
//在堆中申请一个内存空间来存放节点
book = (struct Book *)malloc(sizeof(struct Book));
if (book == NULL)
{
printf("内存分配失败");
exit(1);
}
//填充信息域
getInput(book);
//如果头指针没有指向NULL,那么借助临时变量保存地址
if (*library != NULL)
{
temp = *library;
*library = book;
book->next = temp;
}
//如果头指针指向NULL,则指向新建节点
else
{
*library = book;
book->next = NULL;
}
}
int main(void)
{
//head指针
struct Book *library = NULL;
addBook(&library);
return 0;
}
打印单链表及头插法完整部分如下:
举个栗子:
#include <stdio.h>
#include <stdlib.h>
//单链表节点的声明
struct Book
{
char title[128];
char author[40];
struct Book *next;
};
//函数声明
void getInput(struct Book *book);
void addBook(struct Book **library);
void printLibrary(struct Book *library);
void releaseLibrary(struct Book **library);
//填充信息域
void getInput(struct Book *book)
{
printf("请输入书名:");
scanf("%s",book->title);
printf("请输入作者:");
scanf("%s",book->author);
}
//这里**是因为library指针中存放的值是需要修改的,因此,要将指针的地址传进来,就是指向Book结构体指针的指针
void addBook(struct Book **library)
{
struct Book *book, *temp;
//在堆中申请一个内存空间来存放节点
book = (struct Book *)malloc(sizeof(struct Book));
if (book == NULL)
{
printf("内存分配失败");
exit(1);
}
//填充信息域
getInput(book);
//如果头指针没有指向NULL,那么借助临时变量保存地址
if (*library != NULL)
{
temp = *library;
*library = book;
book->next = temp;
}
//如果头指针指向NULL,则指向新建节点
else
{
*library = book;
book->next = NULL;
}
}
//打印单链表
void printLibrary(struct Book *library)
{
struct Book *book;
int count = 1;
book = library;
while (book != NULL)
{
printf("Book%d: \n",count);
printf("书名:%s\n",book->title);
printf("作者:%s\n",book->author);
//移动一位
book = book->next;
count++;
}
}
//释放内存空间
void releaseLibrary(struct Book **library)
{
struct Book *temp;
while (*library != NULL)
{
temp = *library;
*library = (*library)->next;
free(temp);
}
}
int main(void)
{
//head指针
struct Book *library = NULL;
int ch;
while (1)
{
printf("请问是否需要录入书籍信息(Y/N):");
do
{
ch = getchar();
}while (ch != 'Y' && ch != 'N');
if (ch == 'Y')
{
addBook(&library);
}
else
{
break;
}
}
printf("请问是否需要打印图书信息(Y/N):");
do
{
ch = getchar();
}while (ch != 'Y' && ch != 'N');
if (ch == 'Y')
{
printLibrary(library);
}
//释放内存空间
releaseLibrary(&library);
return 0;
}
[liujie@localhost sle43]$ gcc test.c && ./a.out
请问是否需要录入书籍信息(Y/N):Y
请输入书名:《零基础入门Python》
请输入作者:小甲鱼
请问是否需要录入书籍信息(Y/N):Y
请输入书名:《带你学C带你飞》
请输入作者:小甲鱼
请问是否需要录入书籍信息(Y/N):N
请问是否需要打印图书信息(Y/N):Y
Book1:
书名:《带你学C带你飞》
作者:小甲鱼
Book2:
书名:《零基础入门Python》
作者:小甲鱼
2.尾插法
其代码实现为:
#include <stdio.h>
#include <stdlib.h>
//单链表节点的声明
struct Book
{
char title[128];
char author[40];
struct Book *next;
};
//函数声明
void getInput(struct Book *book);
void addBook(struct Book **library);
void printLibrary(struct Book *library);
void releaseLibrary(struct Book **library);
//填充信息域
void getInput(struct Book *book)
{
printf("请输入书名:");
scanf("%s",book->title);
printf("请输入作者:");
scanf("%s",book->author);
}
//这里**是因为library指针中存放的值是需要修改的,因此,要将指针的地址传进来,就是指向Book结构体指针的指针
void addBook(struct Book **library)
{
struct Book *book, *temp;
//在堆中申请一个内存空间来存放节点
book = (struct Book *)malloc(sizeof(struct Book));
if (book == NULL)
{
printf("内存分配失败");
exit(1);
}
//填充信息域
getInput(book);
//如果头指针没有指向NULL,那么借助临时变量保存地址
if (*library != NULL)
{
temp = *library;
//定位单链表的尾部
while (temp->next != NULL)
{
temp = temp->next;
}
//插入数据
temp->next = book;
book->next = NULL;
}
//如果头指针指向NULL,则指向新建节点
else
{
*library = book;
book->next = NULL;
}
}
//打印单链表
void printLibrary(struct Book *library)
{
struct Book *book;
int count = 1;
book = library;
while (book != NULL)
{
printf("Book%d: \n",count);
printf("书名:%s\n"