(二)链表学习之模块化处理

1.动态链表概念

动态链表就是由malloc分配内存

2.动态链表操作接口

2.0数据结构定义

struct Student {
	int num;//编号
	float score;//成绩
	struct Student* next;//存储下一个节点的地址
};
typedef struct Student ST;

2.1添加节点

void add(ST** phead, int inum, float iscore)//传入头节点的地址,插入数据
{
	if (*phead == NULL)//判断链表是否为空
	{
		ST* newnode = malloc(sizeof(ST));//c99可以不强转malloc返回值
		if (newnode == NULL)
		{
			printf("内存分配失败");
			return;
		}
		newnode->num = inum; //节点初始化
		newnode->score = iscore;
		newnode->next = NULL;
		*phead = newnode;//让头指针指向这个节点
	}
	else
	{
		ST* p = *phead;
		while (p->next != NULL)//遍历到最后1个节点,尾部插入
		{
			p = p->next;
		}

		ST* newnode = malloc(sizeof(ST));
		if (newnode == NULL)
		{
			printf("内存分配失败");
			return;
		}
		newnode->num = inum; //节点初始化
		newnode->score = iscore;
		newnode->next = NULL;
		p->next = newnode;//让头指针指向这个节点
	}
}

2.2显示节点数据

void showall(ST* phead)//传入头节点,显示所有数据
{
	ST* head = phead;
	while (head != NULL)
	{
		printf("num=%d,score=%f", head->num, head->score);//访问数据
		printf("%p,%p\n", head, head->next);//打印两个节点的地址
		head = head->next;
	}
}

2.3逆转节点

ST* rev(ST* head)//逆转
{
	ST* p1, * p2, * p3;
	p1 = p2 = p3 = NULL;
	if (head == NULL || head->next == NULL)//为空链表或者只有1个元素
	{
		return head;//返回头节点
	}
	p1 = head;
	p2 = head->next;
	while (p2!=NULL)
	{
		p3 = p2->next;//布局三个节点
		p2->next = p1;//指向前一个节点
		p1 = p2;//指针向前移动,从第二个到最后一个节点
		p2 = p3;
	}
	head->next = NULL;
	head = p1;
	return head;
}

2.4查找节点

ST* search(ST* head, int num)//根据编号查找节点
{
	while (head != NULL)
	{
		if (num == head->num)
		{
			return head;//返回当前节点的指针地址
		}
		head = head->next;
	}
	return NULL;
}

2.5查找并修改节点数据

void change(ST* head, int oldnum, int newnum)//查找oldnum修改为newnum
{
	ST* psearch = search(head, oldnum);
	if (psearch == NULL)
	{
		printf("没找到");
	}
	else
	{
		psearch->num = newnum;
		printf("修改成功");
	}
}

2.6获取节点个数

int getnum(ST* head)//获取节点个数
{
	int i = 0;
	while (head != NULL)
	{
		i++;
		head = head->next;
	}
	return i;
}

2.7删除所有节点

void *freeall(ST* head)//删除所有节点.每次删除第一个节点后面的一个节点,最后删除头节点
{
	ST* p1, * p2;
	p1 = p2 = NULL;
	p1 = head;//头节点
	while (p1->next!=NULL)//遍历所有节点
	{
		p2 = p1->next;//p2为p1下个节点
		p1->next = p2->next;//p1存储了p2下一个节点的地址
		//p1->next = p2->next;//p1存储了p2下一个节点的地址
		//p2 = p1->next;//p2为p1下个节点
		free(p2);
		printf("\n\n\n");//访问数据,观测删除过程
		showall(head);
		
	}
	free(head);
	return NULL;
}

2.7删除指定节点

ST* delete(ST *head ,int num)//返回头节点,传入头节点,要删除节点的编号
{
	ST* p1, * p2;
	p1 = p2 = NULL;
	p1 = head;//头节点
	while (p1 != NULL)
	{
		if (p1->num == num)
		{
			break;
		}
		else
		{
			p2 = p1;//记录当前节点
			p1 = p1->next;
		}
	}
	if (p1 == head)
	{
		head = p1->next;
		free(p1);
	}
	else 
	{
		p2->next = p1->next;
		free(p1);
	}
	return head;
}

2.8根据节点,头部插入

ST* HeadInsert(ST* head, int num, int inum, float iscore)//根据节点,头部插入
{
	ST* p1, * p2;
	p1 = p2 = NULL;//定义两空节点
	p1 = head;
	while (p1 != NULL)
	{
		if (p1->num == num)
		{
			break;
		}
		else
		{
			p2 = p1;//记录当前节点
			p1 = p1->next;//循环到下一个节点
		}
	}
	if (head == p1)//头节点
	{
		ST* newnode = (ST *)malloc(sizeof(ST));
		newnode->num = inum;
		newnode->score = iscore;
		newnode->next = head;//指向第一个节点
		head = newnode;//newnode成为第一个节点
	}
	else
	{
		ST* newnode = (ST*)malloc(sizeof(ST));
		newnode->num = inum;
		newnode->score = iscore;
		newnode->next = p1;//新节点指向p1
		p2->next = newnode;//指向新节点
	}
	return head;
}

2.8根据节点,尾部插入

ST* BackInsert(ST* head, int num, int inum, float iscore)//根据节点,尾部插入
{
	ST* p1, * p2;
	p1 = p2 = NULL;//定义两空节点
	p1 = head;
	while (p1 != NULL)
	{
		if (p1->num == num)
		{
			break;
		}
		else
		{
			//p2 = p1;//记录当前节点
			p1 = p1->next;//循环到下一个节点
		}
	}
	if (p1->next == NULL)//最后一个节点
	{
		ST* newnode = (ST*)malloc(sizeof(ST));
		newnode->num = inum;
		newnode->score = iscore;
		newnode->next = NULL;
		p1->next = newnode;
	}
	else
	{
		p2 = p1->next;//记录下一个节点的位置
		ST* newnode = (ST*)malloc(sizeof(ST));
		newnode->num = inum;
		newnode->score = iscore;
		newnode->next = p2;//链接下一个节点
		p1->next = newnode;//p1指向新节点
	}
	return head;//无意义
}

2.9节点排序

void sort(ST* head,char ch)//当ch为大于号则从大到小排序,冒泡排序
{
	if (ch == '>')
	{
		for (ST* p1 = head; p1 != NULL; p1 = p1->next)
		{
			for (ST* p2 = head; p2 != NULL; p2 = p2->next)
			{
				if (p1->num < p2->num)
				{
					ST temp;
					temp.num = p1->num;
					p1->num = p2->num;
					p2->num = temp.num;
					//再交换score
				}
			}
		}
	}
	else if (ch == '<')
	{

	}

}

2.10主程序

int main()
{
	struct Student* head = NULL;//头指针,指向节点,从而访问节点

	add(&head, 1, 70);
	add(&head, 2, 80);
	add(&head, 3, 90);
	add(&head, 4, 91);
	add(&head, 5, 92);

	//printf("%d,%f\n", head->num, head->score);//访问数据
	//printf("%d,%f\n", head->next->num, head->next->score);
	//printf("%d,%f\n", head->next->next->num, head->next->next->score);
	head = rev(head);
	showall(head);
	
	//head= freeall(head);
	//head = NULL;//删除头节点务必让他为空
	showall(head);

	system("pause");
	return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值