鱼C代码笔记整理

一、单链表

(1)头插法

#include<stdio.h>
#include<stdlib.h> 

struct Book//一个单链表的声明(结构体内包括信息域成员,和下一个节点的指针/地址) 
{
	char title[128];//title"标题“ 
	char author[40];//author”作家“ 
	struct Book *next;//下一个节点的指针(地址) 
};

void getInput(struct Book *book)//传入新的节点的地址 ,以达到给新节点赋值的目的,在函数外部赋值需要传入数据所在的地址 
{
	printf("请输入书名:");
	scanf("%s",book->title);//指针指向结构体成员使用-> 
	printf("请输入作者:");
	scanf("%s",book->author);
}

void addBook(struct Book **library)//添加新的节点(头插法)//头插法,插入节点,是把头指针的地址改了,也就是把指向头指针的指针改了,所以我们需要对传入的头指针进行解引用,找到指向头指针的指针,并修改它;(头指针只是一个存放第一个节点的地址的指针变量) 
{// void addBook(struct Book *library)改的是存放在library里的数据,void addBook(struct Book **library)才能修改指针本身的地址,指针本身的地址才是第一个节点的地址; 
	struct Book *book,*temp;//*book,创建了我们需要添加的节点的指针/地址名(只是一个声明) ;*temp,意为”临时工“,一般作为空的临时变量使用 
	
	book=(struct Book *)malloc(sizeof(struct Book));//给新添加的指针分配地址:(数据类型)malloc(所申请的数据长度) --> (数据类型)malloc(sizeof(数据类型))
	if(book==NULL)//如果book==NULL也就是内存分配失败的话,我们给出提醒,并终止整个程序 
	{
		printf("内存分配失败!\n");
		exit(1);// exit()是个函数,意为“出口”,需要头文件#include<stdlib.h>, 传入1表示程序异常,立即终止;传入0则表示程序正常运行; 
	}
	
	getInput(book);//自定义函数,意为“获取输入”,让用户填入新节点的信息(填充信息域),传入book ,相当于把 struct Book *book=右边的值送过去赋值
	//有两种情况,头指针一开始是指向NULL的,也就是说这是一个空链表;还有一种情况,头指针是指向节点的,这不是一个空链表; 
	if(*library!=NULL)//不是空链表时 
	{
		temp=*library;//先把头指针中存放的原第一个节点的地址保存在临时变量temp中 
		*library=book;//然后把头指针指向新的第一个节点的地址 
		book->next=temp;//最后把新的第一个节点的结构体成员(也就是存放下一个节点地址的地方)指向原第一个节点的地址 
	}
	else//是空链表时 
	{
		*library=book;//把头指针指向新添加的节点的地址 
		book->next=NULL;//然后把新添加的节点中的结构体成员(结构体中的指针域)指向NULL 
	} 
}

void printlibrary(struct Book *library)//打印链表内容 
{
	struct Book *book;//新指针,跟其他的重名但其实无关,是个只存在于printlibrary函数内的新的指针变量 
	int count=1;//计数器 
	
	book=library;//用新的指针变量来拷贝头指针(保证接下来的操作不会修改到真正的头指针) 
	while(book!=NULL)//这个循环用来遍历链表,从头指针一直指向下一个节点,直到指向NULL时表示链表结束,停止循环 
	{
		printf("Book%d:",count);//记录这是第几本书 
		printf("书名:%s",book->title); 
		printf("作者:%s",book->author);
		book=book->next;//把下一个节点的地址给book,循环继续 
		count++;
	} 
}

void releaselibrary(struct Book **library)//release意为“释放”,这个函数用来释放链表,所以我们传入头指针 
{
	struct Book *temp;//定义一个临时变量来保留头指针 
	while(*library!=NULL)//只要这个链表的头指针不指向NULL,也就是说它不是一个空链表时,我们就要进行以下步骤释放链表占用的内存空间 
	{
		temp=*library;
		*library=(*library)->next;//指向下一个节点 
		free(temp);//free()函数,用来手动释放我们手动申请的动态内存空间  
	} 
}

int main()
{
	int ch;
	struct Book *library=NULL;//创建了头指针,并且指向NULL说明是一个空的头指针,也就是一个空的链表; 
	//addBook(&library);//传入头指针的地址,然后就可以在addBook函数内修改头指针所指向的数据(把NULL改了) 
	
	while(1)//进入死循环,不断的询问是否要录入信息,直到用户输入正确 
	{
		printf("请问是否需要录入书籍信息(Y/N):");
		do//不管三七二十一,输入一次 
		{
			ch=getchar();//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);//最后手动释放链表,因为链表可能都是通过malloc函数申请的动态内存空间,不自动释放的话会一直占用内存空间 
			
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值