2020.10.9 第14课 结构体终结篇

一、静态链表

1.认识链表

类型区别
有头链表没有存数据、表头节点无数据域
无头链表存数据、表头节点有数据域

在这里插入图片描述

2.链表怎么表示

struct Node
{
	//struct MM data;
	int data;            数据域
	struct Node* next;	 指针域
};

int main()
{
	struct Node node1 = { 1,NULL };
	struct Node node2 = { 2,NULL };
	struct Node node3 = { 3,NULL };
	node1.next = &node2;
	node2.next = &node3;
	

3.链表如何打印

一般通过移动指针操作

struct Node* pMove = &node1;
while (pMove != NULL)
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;
	}

二、动态链表

意思:自动链接 用户只需要输入就可

1.创建表头

//用第一个节点表示整个链表
//有头链表: 1.创建表头—>创建结构体变量
//用指针表示结构体变量?1.用变量地址初始化,2.动态内存申请

1.创建表头 结构体变量 指针表示的 动态内存申请的
struct Node* createHead() 
{
	//1.动态内存申请
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	//(*headNode).next = NULL;
	headNode->next = NULL;
	return headNode;
}

在这里插入图片描述

2.创建节点

//2创建节点—>把用户数据加工节点
//为插入准备 指针作为链表结束标志

2.创建节点 把用户数据加工成节点  未插入做准备
struct Node* createNode(int data) 
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;  //作为链表结束标志
	return newNode;
}

在这里插入图片描述

3.表头插入

要插入的节点,表头节点(链表)

3.表头插入
自己写时候,参数要能够解释出意思
以headNode 为表头链表
插入的数据是data
void insertByHead(struct Node* headNode,int data)
{
	struct Node* newNode = createNode(data);	//调用自己写的函数
	//下面两句先后顺序不能交换
	//先连后断
	newNode->next = headNode->next;
	headNode->next = newNode;
	/*
		headNode->next = newNode;
		newNode->next = headNode->next;  //newNode->next = newNode
	*/
}

4.表尾插入

要插入的节点,表尾节点

4.表尾插入
void insertByTail(struct Node* headNode, int data) 
{
	struct Node* newNode = createNode(data);
	struct Node* pTail = headNode;
	while (pTail->next != NULL)  遍历到表尾之后
	{
		pTail = pTail->next;
	}
	pTail->next = newNode; 才能在表尾插入新的节点
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-bR9wdxCA-1602263708207)(C:\Users\lizhigang\AppData\Roaming\Typora\typora-user-images\image-20201010010955442.png)]

5.指定位置插入

/5.指定位置插入
/data:插入的数据
/posData: 指定位置
void insertByAppoin(struct Node* headNode, int data, int posData) 
{
	做这种查找类插入,先不要着急创建节点?考虑没找到情况
	struct Node* frontNode = headNode;struct Node* posNode = headNode->next;	右
	注意: && 短路处理
	posNode != NULL作为找到表尾的退出条件
	当posNode等于NULL ,NULL->data 的非法访问
	//frontNode->next!=NULL&&posNode->data != posData
	while (posNode != NULL && posNode->data != posData )
	{
		//frontNode = frontNode->next;
		//posNode = posNode->next;
		frontNode = posNode;
		posNode = frontNode->next;  //posNode=posNode->next;
		//frontNode 是posNode左边
		//最后一节点:frontNode  posNode就是NULL
	}
	退出循环,分析讨论是否找到
	if(posNode==NULL)
	{
		printf("%d\t", frontNode->data);
		printf("未找到,无法插入信息!\n");
	}
	else
	{
		struct Node* newNode = createNode(data);
		frontNode->next = newNode;
		newNode->next = posNode;
	}
}

在这里插入图片描述

6.表头删除

打狗要看主人: 把一个节点下一个删除,要考虑删除节点上一节点next
不能删除NULL的东西
6.表头删除
void deleteByHead(struct Node* headNode) 
{
	struct Node* nextNode = headNode->next;
	if (nextNode != NULL)   防御性编程
	{
		headNode->next = nextNode->next;
		free(nextNode);
		nextNode = NULL;
	}
}

在这里插入图片描述

7.表尾删除

7.表尾删除
void deleteByTail(struct Node* headNode)
{
	struct Node* frontNode = NULL;
	struct Node* tailNode = headNode;  //NULL;
	while (tailNode->next != NULL) //NULL->next!=NULL
	{
		frontNode = tailNode;
		tailNode = frontNode->next;
	}
	if (frontNode == NULL) 
	{
		printf("表为NULL,删除失败\n");
	}
	else 
	{
		frontNode->next = NULL;
		free(tailNode);
		tailNode = NULL;
	}
}

8.指定位置删除

8.指定位置删除
void deleteByAppoin(struct Node* headNode, int posData) 
{
	struct Node* frontNode = headNode;
	struct Node* posNode = headNode->next;
	while (posNode != NULL && posNode->data != posData) 
	{
		frontNode = posNode;
		posNode = frontNode->next;
	}
	if (posNode == NULL) 
	{
		printf("未找到,无法删除!\n");
	}
	else 
	{
		frontNode->next = posNode->next;
		free(posNode);
		posNode = NULL;
	}
}

在这里插入图片描述

9.遍历.打印

9.遍历--->打印
void printList(struct Node* headNode) 
{
	//为什么指向第二个节点? 因为第一个节点没有存数据
	struct Node* pMove = headNode->next;
	while (pMove != NULL) 
	{
		printf("%d\t", pMove->data);
		pMove = pMove->next;
	}
	printf("\n");
}

10.测试

int main() 
{
	struct Node* list = createHead();
	for (int i = 0; i < 3; i++) 
	{
		insertByHead(list, i);
	}
	printList(list);
	insertByTail(list, 100);
	printList(list);
	insertByAppoin(list, 99, 100);
	printList(list);
	insertByAppoin(list, 102, 112122);
	insertByAppoin(list, 102, 2);
	printList(list);
	deleteByHead(list);
	printList(list);
	deleteByTail(list);
	printList(list);
	deleteByAppoin(list, 1);
	printList(list);
	return 0;
}

在这里插入图片描述

三、链表在项目中的使用


	链表: 充当数据的容器
		可以灵活存取数据
管理系统
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct MM 
{
	char name[20];
	int age;
	int num;
	char addr[20];
};

struct Node
{
	//int data;
	struct MM data;
	struct Node* next;
};
struct Node* list = NULL;

struct Node* createHead()
{
	//1.动态内存申请
	struct Node* headNode = (struct Node*)malloc(sizeof(struct Node));
	//(*headNode).next = NULL;
	headNode->next = NULL;
	return headNode;
}
struct Node* createNode(struct MM  data)
{
	struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
	newNode->data = data;
	newNode->next = NULL;  //作为链表结束标志
	return newNode;
}

void insertByHead(struct Node* headNode, struct MM data)
{
	struct Node* newNode = createNode(data);	//调用自己写的函数
	//下面两句先后顺序不能交换
	//先连后断
	newNode->next = headNode->next;
	headNode->next = newNode;
}
//8.指定位置删除
void deleteByName(struct Node* headNode, char *mmName)
{
	struct Node* frontNode = headNode;
	struct Node* posNode = headNode->next;
	while (posNode != NULL && strcmp(posNode->data.name , mmName))
	{
		frontNode = posNode;
		posNode = frontNode->next;
	}
	if (posNode == NULL)
	{
		printf("未找到,无法删除!\n");
	}
	else
	{
		frontNode->next = posNode->next;
		free(posNode);
		posNode = NULL;
	}
}

struct Node* searchByName(struct Node* headNode, char* mmName) 
{
	struct Node* pMove = headNode->next;
	while (pMove != NULL && strcmp(pMove->data.name, mmName)) 
	{
		pMove = pMove->next;
	}
	return pMove;
}

//9.遍历--->打印
void printList(struct Node* headNode)
{
	//为什么指向第二个节点? 因为第一个节点没有存数据
	struct Node* pMove = headNode->next;
	//表头
	printf("姓名\t年龄\t编号\t地址\n");
	while (pMove != NULL)
	{
		//printf("%d\t", pMove->data);
		printf("%s\t%d\t%d\t%s\n", pMove->data.name, pMove->data.age, pMove->data.num, pMove->data.addr);
		pMove = pMove->next;
	}
	printf("\n");
}
void makeMenu() 
{
	printf("------------MM 管理系统 ---------\n");
	printf("\t\t0.退出系统\n");
	printf("\t\t1.录入系统\n");
	printf("\t\t2.浏览信息\n");
	printf("\t\t3.删除信息\n");
	printf("\t\t4.修改信息\n");
	printf("\t\t5.查找信息\n");
	printf("-----------------------------------\n");
}
void keyDown() 
{
	int userKey = 0;
	struct MM tempData;
	struct Node* result = NULL;
	scanf("%d", &userKey);
	switch (userKey) 
	{
	case 0:
		printf("正常退出!\n");
		system("pause");
		exit(0);
		break;
	case 1:
		printf("name,age,num,addr:");
		scanf("%s%d%d%s", tempData.name, &tempData.age, &tempData.num, tempData.addr);
		insertByHead(list, tempData);
		break;
	case 2:
		printList(list);
		break;
	case 3:
		printf("input Name:");
		scanf("%s", tempData.name);
		deleteByName(list, tempData.name);
		break;
	case 4:
		printf("input Name:");
		scanf("%s", tempData.name);
		result = searchByName(list, tempData.name);
		if (result == NULL)
		{
			printf("未找到\n");
		}
		else
		{
			printf("input new name,age,num,addr:");
			scanf("%s%d%d%s", result->data.name, &result->data.age, &result->data.num, result->data.addr);
		}
		break;
	case 5:
		printf("input Name:");
		scanf("%s", tempData.name);
		result = searchByName(list, tempData.name);
		if (result == NULL) 
		{
			printf("未找到\n");
		}
		else 
		{
			printf("姓名\t年龄\t编号\t地址\n");
			printf("%s\t%d\t%d\t%s\n", result->data.name, result->data.age, result->data.num, result->data.addr);
		}
		break;
	default:
		printf("请重新输入!\n");
		break;
	}
}
int main()
{
	list = createHead();
	while (1) 
	{
		makeMenu();
		keyDown();
		system("pause");
		system("cls");
	}
	return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值