栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

头插法 (单链表)-----鱼c小甲鱼笔记

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

头插法 (单链表)-----鱼c小甲鱼笔记

 链表=信息域+指针域
链表中的信息域通过指针连接在一起
head   null
信息域存放链表中某个结点的内容,这里的结点相当于数组里的元素
指针域用来指向下一个跟它一模一样的结点
结点之间用指针串联
直到最后一个结点的指针域指向null结束
链表中各个元素不是紧密相连的,它们之间通过指针相连
所以对于之前的book结构来说,要把它变成链表中的一个结点,需要为它添加一个指向自身的成员
-------------------------------------------------------------------------------------------------------------------------
插入元素
首先在堆里申请一个新的内存空间,用来存放这个新的结点,然后填充这个新结点的信息域,然后把head指针原来的指向擦除,然后指向新结点,新结点的指针域指向原来head指向的那个信息域       头插法

-------------------------------------------------------------------------------------------------------------------------
书籍插入单链表的代码解释
声明一个addBook函数,因为该函数需要一个参数,所以在main函数里申请一个struct Book *library(这里实际指的就是头指针head)=null,刚开始指向null,说明这是一个空的单链表,通过调用addBook把新的结点插入,要插入新的结点,就需要修改head的值,因为head存放的是它原来所指向的那个信息域的地址,所以需要把head里存的内容改成将要添加的那个结点的信息域的地址,让新插入的那个结点的指针域指向head原来指向的那个信息域

-------------------------------------------------------------------------------------------------------------------------
 代码部分     
修改library部分,对它进行两层解引用。此时addBook函数的参数是一个指向book结构的指针的指针   主函数里调用addBook函数,里面的参数应该是&library,不能是library,因为如果是library的话,此时传入的是原来head指向的那个信息域,但是我们要修改的是head,所以应该给head的地址,修改head的值       重新看addBook函数,动态的在内存里调用malloc函数来申请一个book结构sizeof(struct Book),因为返回的是void函数类型,所以把它强制转化为book的结构体类型     (struct Book*) 强制转化


内存分配完以后要填充信息域,即让用户输入信息。这个用自定义的getInput函数实现,函数传递的参数就是book的地址

传给这个函数的是一个book结构的指针,直接传个指针,然后通过指针修改结合体的内容就可以了      输入书名时,因为传过来的是指针,所以直接用箭头的这个操作符指向title

再返回去看addBook函数,接下来有两种情况,就是要么library传过来的head是一个空的单链表即,library这个指针指向null,此时就把library这个指针指向新生成的这个book结点,把book->next指向null;反之,先把head原来存储的地址的值用一个临时变量tmp存放起来,然后让head指向新的结点的信息域,再把tmp的值给这个新结点的指针域   

两个星号的原因:我们要修改的这个head存放的内容的值,即library指针自身的值,所以我们需要把指针的地址传进去,而这个指针是一个指向book结构体的指针,把指针的地址传进去,所以需要一个指向book结构体指针的指针

-------------------------------------------------------------------------------------------------------------------------

如何打印单链表里的成员

声明一个printLibrary函数    book=book->next的意思是指向下一个结点

最后记得用releaseLibrary函数释放掉malloc申请的空间

看向主函数   提高用户体验   (while循环内即下面的东西)

-------------------------------------------------------------------------------------------------------------------------
头插法 比较慢录入的内容在前面 ,尾插法在单链表的后面

-------------------------------------------------------------------------------------------------------------------------
在写释放单链表的代码时犯的错误
先调用free函数将library指向的内存空间释放掉,然后将library指向下一个结点,这里存在一个问题,把library的空间释放掉以后,就无法过去这个空间的next成员了,所以理论上library=library->next这个语句是没有意义的。

                                                        之前的错误代码:

修改方法:
增加一个临时变量,在释放之前把这个结点的地址先保存下来。  声明部分也进行了修改
releaseLibrary函数调用时也改为library的地址
->的优先级比*高

 

 

 

#include 
#include 

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);
}

void addBook(struct Book **library) {
	struct Book *book, *temp;
	book = (struct Book *)malloc(sizeof(struct Book));
	if (book == NULL) {
		printf("内存分配失败n");//通常不会
		exit(1);//用于强制退出,需要头文件stdlib.h
	}
	getInput(book);

	if (*library != NULL) {
		temp = *library;
		*library = book;
		book -> next = temp;

	} 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:", count);
		printf("书名:%s", book->title);
		printf("作者:%s", 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) {
	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;
}

 如果出现问题,欢迎批评指正啊

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/954788.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号