数据结构(C语言版)--单链表基本操作的实现用图书管理系统作为演示

----基于对数据结构(C语言版)中单链表基本操作的实现与演示,本篇文章以图书管理系统做演示

一. 单链表的初始化(尾插法)

尾插法算法:1.申请一个指针*p始终让它指向最后一个结点。

                   2.生成一个新的结点*book,并给它的数据域赋值。

                   3.将新结点*book插入尾结点*p的next域。

                   4.将*p指向新的尾结点*book。

Getbook函数用于给新结点赋值在Createlibrary函数中被调用。

void Getbook(Library *book)//给新结点赋值
{
	printf("请输入序号 书名 价格\n");
	scanf("%d %s %f",&book->isbn,book->name,&book->money);
}
void Createlibrary(Library **head)//传入head头指针,因为需要改变指针指向的地址所以这里的形参传入二级指针 
{
    //构造一个单链表
	Library *p = *head;//尾插法 申请一个变量记录最后一个节点的位置 
	int isbn;//图书的序号
	
	printf("isbn = -1 退出停止录入\n");//isbn等于-1时停止录入数据,用isbn作为循环的判断条件
	scanf("%d",&isbn);
	
	while(isbn!=-1)
	{
	Library *book = (Library*)malloc(sizeof(Library));//创造新的结点申请空间 
		if(book == NULL)
		{
			printf("内存分配失败");
			exit(1); 
		}
	Getbook(book);//录入新结点的内容
	p->next = book;
	book->next = NULL;
	p = book;//用指针p记录最后一个结点的位置
	printf("是否需要继续输入(1/-1):");
	scanf("%d",&isbn);
	}	
}

二.单链表的插入

插入的算法:1.申请一个指针*p用于遍历单链表。

                   2.找到比要插入数据的序号的前一个结点,将它的*next域赋值给新结点的*next域。

                   3.将比isbn大的结点的序号加一。

void Insertbook(Library **head,int isbn)//isbn要插入数据的序号,所有数据序号从1开始 
{
	Library *p,*L;//*p用于遍历 
	p = *head;
	int i=1;
	for(;i<isbn&&p;i++)
	{
		p = p->next;
	}
	if(p)		{printf("插入位置不合法\n"); return ;}//未找到合法的插入位置
	Library *book = (Library*)malloc(sizeof(Library));//为新结点申请空间
	Getbook(book);
	book->next = p->next;//将新结点插入到尾结点之后,变成新的尾结点
	p->next = book;
	L = book->next;
	if(L->isbn==isbn)
	{
		while(L)
		{
			L->isbn++;//将比isbn大的结点序号加一
			L = L->next;
		}
	}
}

三.单链表的删除

删除算法:1.申请三个指针*p用于记录删除数据的直接前驱,*L用于记录删除的数据,*tmp用于释放空间

                2.将问题简单化,分为删除第一个结点,和大于1结点的情况

void Deletebook(Library **head,int isbn)
{
	Library *p,*L,*tmp;//删除数据的前驱L,删掉的数据p,释放内存tmp 
	p = (*head)->next;
	L = *head;//注意必须将指向指针的指针复制给临时变量才能修改指针的指向,完成删除或者插入单链表的操作 
	while(p)//当p不为空时循环执行
	{
		if(isbn==1)
		{
			(*head)->next = p->next;
			break;
		}
		if(p->isbn==isbn)
			{
				tmp = p;
				L->next = p->next;
				free(p);
				tmp = tmp->next;
				while(tmp)
				{
					tmp->isbn--;
					tmp = tmp->next;
				} 
				break;
			}
		p = p->next;//指向下一个结点
		L = L->next;//指向下一个结点
	}
}

四.单链表的查找

查找的算法:1.用指针*p指向头结点

                   2.从首元结点开始依次顺着链表域next向下查找,只要指针p不为空,且指针p的数据域不等于isbn,则p指向下一个结点。

                   3.若查找成功输出p此时的数据域,若查找失败,打印查找失败。

void Findbook(Library *head,int isbn)//*head头指针,isbn要查找的序号
{
	Library *p = head->next;//*p用于遍历
    int flag = 0;//用于记录是否查找成功
	while(p)//当p不为空时循环执行
	{
		if(p->isbn==isbn)
		{
			printf("序号:%d 书名:%s\n",p->isbn,p->name);
			printf("价格:%.2f\n",p->money);
            flag = 1;
		}
		p = p->next;//指向下一个结点
	}
    if(flag==0)
    printf("未找到该元素");
}

五.单链表数据域的修改

修改的算法.1:用指针p指向头结点

                   2:从首元结点开始依次向下遍历单链表,只要p不为空,或者p的数据域不等于isbn,则指向下一个结点。

void Modifybook(Library *head,int isbn)//head为头指针,isbn为修改结点的序号
{
	Library *p = head->next;//将*p指向头结点
	int num=0;//switch语句的判断条件
	for(int i = 1;p;i++)
	{
		if(p->isbn==isbn)
		{
			printf("需要修改 1-序号-2书名-3价格(1/2/3):");
			scanf("%d",&num);//用于判断要修改的数据
			switch(num){
				case 1:printf("请输入新的序号:");
					   scanf("%d",&p->isbn);
					   break;
				case 2:printf("请输入新的书名:");
					   scanf("%s",&p->name);
					   break;
				case 3:printf("请输入新的价格:");
					   scanf("%f",&p->money);
					   break;
				default : break;		
			}
		}
		p = p->next;//指向下一个结点
	}
}

六.单链表空间的释放。

释放空间的算法:1.将p指向头指针

                          2.从首元结点开始依次利用free函数释放空间,直至p为空。

void FreeLibrary(Library *head) {
    Library *p = head;//用于遍历单链表
    while (p) {
        Library *temp = p;
        p = p->next;
        free(temp);
    }
}

七.单链表的计数

算法:1.将p指向头结点

        2.从首元结点开始依次遍历单链表,每次循环只要p不为空,num加一记录结点数量

        3.最后返回num。

int Countbook(Library *head)
{
	int num = 0;//返回计数结果的变量
	Library *p = head->next;
	while(p)
	{
		num++;
		p = p->next;
	}
	return num;
}

八.图书管理系统的代码实现

#include <stdio.h>	
#include <stdlib.h>
//功能:创建 查找 插入 删除 修改 计数 

typedef struct Library{
	int isbn;//序号 
	char name[20];
	float money;
	Library *next;
};
void Createlibrary(Library **head);//创建单链表 
void Getbook(Library *book);//书籍信息输入 
void Printfbook(Library *book);//打印书籍 
void Insertbook(Library **book,int isbn);//插入书籍 
void FreeLibrary(Library *head);//释放内存 
void Deletebook(Library **head,int isbn);//删除书籍 
void Modifybook(Library *head,int isbn);//修改书籍
void Findbook(Library *head,int isbn);//查找书籍 
int  Countbook(Library *head);//计数 
void Getbook(Library *book)
{
	printf("请输入序号 书名 价格\n");
	scanf("%d %s %f",&book->isbn,book->name,&book->money);
}

void Createlibrary(Library **head)//head 头节点  
{
	Library *p = *head;//尾插法 申请一个变量记录最后一个节点的位置 
	int isbn;
	
	printf("isbn = -1 退出停止录入\n");
	scanf("%d",&isbn);
	
	while(isbn!=-1)
	{
	Library *book = (Library*)malloc(sizeof(Library));//创造新的节点申请空间 
		if(book == NULL)
		{
			printf("内存分配失败");
			exit(1); 
		}
	Getbook(book);
	p->next = book;
	book->next = NULL;
	p = book;
	printf("是否需要继续输入(1/-1):");
	scanf("%d",&isbn);
	}	
}

void Printfbook(Library *head)
{
	Library *L;//获取头节点的位置 
	L = head->next;
	while(L)
	{
		printf("序号:%d 书名:%s\n",L->isbn,L->name);
		printf("价格:%.2f\n",L->money);
		putchar('\n');
		L = L->next;
	}
}

void Insertbook(Library **head,int isbn)//isbn要插入数据的序号,所有数据序号从1开始 
{
	Library *p,*L;//p用于遍历 
	p = *head;
	int i=1;
	for(;i<isbn&&p;i++)
	{
		p = p->next;
	}
	if(p)		{printf("插入位置不合法\n"); return ;}
	Library *book = (Library*)malloc(sizeof(Library));
	Getbook(book);
	book->next = p->next;
	p->next = book;
	L = book->next;
	if(L->isbn==isbn)
	{
		while(L)
		{
			L->isbn++;
			L = L->next;
		}
	}
}

void FreeLibrary(Library *head) {
    Library *p = head;
    while (p) {
        Library *temp = p;
        p = p->next;
        free(temp);
    }
}

void Deletebook(Library **head,int isbn)
{
	Library *p,*L,*tmp;//删掉数据的前驱L,删掉的数据p,释放内存tmp 
	p = (*head)->next;
	L = *head;//注意必须将指向指针的指针复制给临时变量才能修改指针的指向,完成删除或者插入单链表的操作 
	while(p)
	{
		if(isbn==1)
		{
			(*head)->next = p->next;
			break;
		}
		if(p->isbn==isbn)
			{
				tmp = p;
				L->next = p->next;
				free(p);
				tmp = tmp->next;
				while(tmp)
				{
					tmp->isbn--;
					tmp = tmp->next;
				} 
				break;
			}
		p = p->next;
		L = L->next;
	}
}
void Modifybook(Library *head,int isbn)
{
	Library *p = head->next;
	int num=0;
	for(int i = 1;p;i++)
	{
		if(p->isbn==isbn)
		{
			printf("需要修改 1-序号-2书名-3价格(1/2/3):");
			scanf("%d",&num);
			switch(num){
				case 1:printf("请输入新的序号:");
					   scanf("%d",&p->isbn);
					   break;
				case 2:printf("请输入新的书名:");
					   scanf("%s",&p->name);
					   break;
				case 3:printf("请输入新的价格:");
					   scanf("%f",&p->money);
					   break;
				default : break;		
			}
		}
		p = p->next;
	}
}

void Findbook(Library *head,int isbn)
{
	Library *p = head->next;
	while(p)
	{
		if(p->isbn==isbn)
		{
			printf("序号:%d 书名:%s\n",p->isbn,p->name);
			printf("价格:%.2f\n",p->money);
		}
		p = p->next;
	}
}

int Countbook(Library *head)
{
	int num=0;
	Library *p = head->next;
	while(p)
	{
		num++;
		p = p->next;
	}
	return num;
}
int main(){
	Library *head = (Library*)malloc(sizeof(Library));//有头结点需要申请空间,next需要存放数据 
	int flag = 0,isbn = 0,num = 0;//flag用于判断 isbn用于记录序号 num用来记录图书数量 
	head->next = NULL;
	Createlibrary(&head);
	printf("是否需要打印图书管理目录(1/-1):");
	scanf("%d",&flag);
	if(flag==1)
	Printfbook(head);
	printf("是否需要添加书籍(1/-1):");
	scanf("%d",&flag);
	if(flag==1)
	{
	printf("请输入书籍序号:");
	scanf("%d",&isbn);
	
	Insertbook(&head,isbn);
	
	printf("请问是否需要重新打印(1/-1):");
	scanf("%d",&flag);
	
	if(flag==1)
		Printfbook(head);
	}
	
	printf("是否需要删除某本书籍(1/-1):");
	scanf("%d",&flag);
	if(flag==1)
	{
		printf("请输入要删掉书籍的序号:");
		scanf("%d",&isbn);
		Deletebook(&head,isbn);
		printf("是否需要打印目录(1/-1):");
		scanf("%d",&flag);
		if(flag==1)		Printfbook(head);
	}
	
	printf("是否需要修改某一书籍(1/-1):");
	scanf("%d",&flag);
	if(flag==1)
	{
		printf("请输入修改书籍的序号:");
		scanf("%d",&isbn);
		Modifybook(head,isbn); 
		Findbook(head,isbn);
	}
	printf("----图书目录最终结果----\n");
	Printfbook(head);
	FreeLibrary(head); 
	return 0;
}

评论 4
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值