数据结构--单链表之图书信息的增删改查(c语言版)

目录

链表内容:

1.创建单链表:

2.初始化链表:

3.链表的信息输入:

4.输出链表内的信息:

 5.按位置插入链表:

6.删除链表 :

 7.查找位置中的元素:

8.按照书号查找位置:

 9.退出:

2.源代码:

3.本人有话说:


链表内容:

1.创建单链表:

typedef struct {
	int id;
	char name[20];
	double price;
} Book;//创建一本书的信息的结构体类型

typedef struct intlist {

	struct intlist* next;//指针域
	Book b;//数据域
} list;//创建链表结点

 

 


2.初始化链表:

通过返回头指针的地址来初始化链表 :想对链表中的域进行操作,就需要知道结list的地址,此时就需要到二级指针,由于二级指针有点绕,因此还有一种方法,用返回值的方式来获取list的地址。

list* initlist() {
	list* head;
	head = (list*)malloc(sizeof(list));
	head->next = NULL;
	return head;
}//初始化链表

 创建一个*head(头节点)的指针变量,给head分配一个list大小的指针类型,然后初始化头节点,将头节点的地址返回(形参),最后在主函数中创建实参来接收head的地址。这样子就可以创建并且初始化头节点了。


3.链表的信息输入:

void creatlist(list* head, int n) {
	list* s, * last;//创建两个指针变量,s为要新建插入节点的指针,last是尾指针
	int i;
	printf("输入%d条数据\n", n);
	last = head;//开始有两个指针指向头节点
	for (i = 0; i < n; i++) {
		s = (list*)malloc(sizeof(list));//分配动态内存,就可以指向数据域跟指针域
		printf("请输入书号\n");
		scanf("%d", &s->b.id);
		printf("请输入书名\n");
		scanf("%s", s->b.name);
		printf("请输入价格\n");
		scanf("%lf", &s->b.price);

		s->next = NULL;
		last->next = s;
		last = s;//尾插法
	}
	printf("链表建立成功!\n");
}//创建链表

这里的信息插入使用的是尾插法,尾插法的核心代码为

        s->next = NULL;
		last->next = s;
		last = s;//尾插法

因此,尾指针永远在最后一个节点处。

代码体现:

 


 

4.输出链表内的信息:

void printflist(list* head) {
	list* p;//创建一个指针变量指向创建好的节点
	p = head->next;//将头节点指向的下一个节点的(即插入的第一个链表)地址赋值给指针p
	while (p != NULL) {
		printf("书号:%d\n", p->b.id);
		printf("书名:%s\n", p->b.name);
		printf("价格:%.2lf\n", p->b.price);
		p = p->next;//历遍链表
	}

}//输出链表

图解: 

 代码体现:


 

 5.按位置插入链表:

void addlist(list* head, int i) {
	int j = 0;//链表下标从0开始,插入位置就是i的值
	list* p, * s;//创建一个寻找插入位置的指针p,一个插入新节点的指针s
	p = head;//从头指针开始寻找
	while (p->next != NULL && j < i - 1) {
		p = p->next;//历遍链表
		j++;//定位要插入的位置
	}//判断循环停止条件为:1.链表为空,2.插入的位置超过当前链表的长度
	if (p != NULL) {
    
		s = (list*)malloc(sizeof(list));//给新插入的节点开辟内存空间
		printf("请输入插入的书号\n");
		scanf("%d", &s->b.id);
		printf("请输入插入的书名\n");
		scanf("%s", s->b.name);
		printf("请输入要插入的价格\n");
		scanf("%lf", &s->b.price);
		s->next = p->next;//先用新节点的指针连接下一个节点
		p->next = s;//在用前一个节点的指针连接新插入的节点
		printf("插入信息成功!!");
	}
	else {
		printf("插入信息失败!!");
	}

}//插入链表

 图解:

 代码体现:


 

6.删除链表 :

void deletelist(list* head, int i) {
	int j = 0;
	Book b;//定义Book类型为b
	list* p = head, * s;//创建指针p指向头指针(用来寻找要删除的位置),*s为二级指针,用于删除节点
	while (p->next != NULL && j < i - 1) {
		p = p->next;
		j++;//定位删除的位置
	}
	if (p->next != NULL && j == i - 1) {
		s = p->next;//此时p->next是要删除的节点的地址,赋值给s
		b = s->b;//将节点里面的数据赋值给结构体类型b
		p->next = s->next;//
		free(s);//释放节点s
		printf("删除第%d位上的数据删除成功!!\n", i);

	}
	else {
		printf("此位置没有数据,删除失败!!!\n");
	}

}//删除数据

 图解:

 代码体现:


 7.查找位置中的元素:

int lengthlist(list* head) {
	list* p = head->next;
	int j = 0;
	while (p != NULL) {
		p = p->next;
		j++;//表长
	}
	return j;//返回表长
}//历遍链表求表长
void getlist(list* head, int i) {
	list* p;
	int j = 0;//链表下标从0开始
	p = head;//创建一个指针p并且指向head
	if (i > lengthlist(head)) {
		printf("未找到该位置,请重新查找\n");
	}//判断查找位置是否大于链表
	while (p->next != NULL && j < i) {
		p = p->next;//历遍链表
		j++;//定位查找的位置
	}
	if (j == i) {
		printf("第%d个位置上的数据为:书号:%d书名:%s价格:%.2lf\n", i, p->b.id, p->b.name, p->b.price);
	}//查找到的条件为j==i(下标j的值等于位置i)
}

 代码体现:


8.按照书号查找位置:

void getlist1(list* head, int i) {
	int j = 1;//由于头节点没有数据,可以从下一个节点开始查找书号
	list* p;
	p = head->next;//创建一个指针指向头节点的下一个节点
	while (p != NULL && p->b.id != i) {
		p = p->next;//历遍链表
		j++;//定位书号的位置
	}
	if (p != NULL) {
		printf("查询的书号为:%d的位置在:%d\n", i, j);
		printf("数据为:书号:%d 书名:%s 价格:%.2lf\n", p->b.id, p->b.name, p->b.price);
	}
	else {
		printf("查询错误,查找不到改书号\n");
	}
}

代码体现:

 


 9.退出:


2.源代码:

#pragma warning (disable:4996)
#include <stdio.h>
#include <malloc.h>


typedef struct {
	int id;
	char name[20];
	double price;
} Book;

typedef struct intlist {

	struct intlist* next;
	Book b;
} list;

list* initlist() {
	list* head;
	head = (list*)malloc(sizeof(list));
	head->next = NULL;
	return head;
}//初始化链表

void welcome() {
	printf("1.写入信息\n");
	printf("2.输出信息\n");
	printf("3.插入信息\n");
	printf("4.删除信息\n");
	printf("5.查找位置上的元素\n");
	printf("6.查找书号的位置\n");
	printf("0.退出\n");
}//欢迎

void creatlist(list* head, int n) {
	list* s, * last;
	int i;
	printf("输入%d条数据\n", n);
	last = head;
	for (i = 0; i < n; i++) {
		s = (list*)malloc(sizeof(list));
		printf("请输入书号\n");
		scanf("%d", &s->b.id);
		printf("请输入书名\n");
		scanf("%s", s->b.name);
		printf("请输入价格\n");
		scanf("%lf", &s->b.price);

		s->next = NULL;
		last->next = s;
		last = s;

	}
	printf("链表建立成功!\n");
}//创建链表

void printflist(list* head) {
	list* p;
	p = head->next;
	while (p != NULL) {
		printf("书号:%d\n", p->b.id);
		printf("书名:%s\n", p->b.name);
		printf("价格:%.2lf\n", p->b.price);
		p = p->next;
	}

}//输出链表


void addlist(list* head, int i) {
	int j = 0;
	list* p, * s;
	p = head;
	while (p->next != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
	if (p != NULL) {

		s = (list*)malloc(sizeof(list));
		printf("请输入插入的书号\n");
		scanf("%d", &s->b.id);
		printf("请输入插入的书名\n");
		scanf("%s", s->b.name);
		printf("请输入要插入的价格\n");
		scanf("%lf", &s->b.price);
		s->next = p->next;
		p->next = s;
		printf("插入信息成功!!");
	}
	else {
		printf("插入信息失败!!");
	}

}//插入链表

void deletelist(list* head, int i) {
	int j = 0;
	Book b;
	list* p = head, * s;
	while (p->next != NULL && j < i - 1) {
		p = p->next;
		j++;
	}
	if (p->next != NULL && j == i - 1) {
		s = p->next;
		b = s->b;
		p->next = s->next;
		free(s);
		printf("删除第%d位上的数据删除成功!!\n", i);

	}
	else {
		printf("此位置没有数据,删除失败!!!\n");
	}

}//删除数据
int lengthlist(list* head) {
	list* p = head->next;
	int j = 0;
	while (p != NULL) {
		p = p->next;
		j++;
	}
	return j;
}
void getlist(list* head, int i) {
	list* p;
	int j = 0;
	p = head;
	if (i > lengthlist(head)) {
		printf("未找到该位置,请重新查找\n");
	}
	while (p->next != NULL && j < i) {
		p = p->next;
		j++;
	}
	if (j == i) {
		printf("第%d个位置上的数据为:书号:%d书名:%s价格:%.2lf\n", i, p->b.id, p->b.name, p->b.price);
	}
}

void getlist1(list* head, int i) {
	int j = 1;
	list* p;
	p = head->next;
	while (p != NULL && p->b.id != i) {
		p = p->next;
		j++;
	}
	if (p != NULL) {
		printf("查询的书号为:%d的位置在:%d\n", i, j);
		printf("数据为:书号:%d 书名:%s 价格:%.2lf\n", p->b.id, p->b.name, p->b.price);
	}
	else {
		printf("查询错误,查找不到改书号\n");
	}


}
int main() {
	int i, n;
	list* head = NULL;
	char ch1, ch2, a;
	Book b;
	ch1 = 'y';
	while (ch1 == 'y') {
		welcome();
		ch2 = getch();
		switch (ch2) {
		case'1':
			head = initlist();//接收返回的形参的地址
			printf("输入多少条数据\n");
			scanf("%d", &n);
			creatlist(head, n);
			break;

		case'2':
			printf("建立后的链表为:\n");
			printflist(head);
			break;

		case'3':
			printf("请输入要插入的位置");
			scanf("%d", &i);
			addlist(head, i);
			printf("插入后的链表为:\n");
			printflist(head);
			break;

		case'4':
			printf("请输入要删除的位置");
			scanf("%d", &i);
			deletelist(head, i);
			printf("删除后的链表为:\n");
			printflist(head);
			break;

		case'5':
			printf("请输入要查找的位置\n");
			scanf("%d", &i);
			getlist(head, i);
			break;

		case'6':
			printf("请输入要查找的书号\n");
			scanf("%d", &i);
			getlist1(head, i);
			break;

		case'0':
			printf("欢迎下次使用\n");
			exit(0);
			break;

		}

	}

}

3.本人有话说:

本人为新手,如果发现代码有什么问题,可以积极私聊我,我虚心改正

  • 32
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃椰子不吐壳

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值