快慢指针与头插法与尾插法(基于C语言)

 快慢指针的妙用

1.找中间值

一般的思路是:先遍历一次链表,记录住一共有多少个节点,然后,再次遍历找寻中点。

利用快慢指针,我们来看看这个问题会变成什么样。思路如下:我们把一个链表看成一个跑道,假设a的速度是b的两倍,那么当a跑完全程后,b刚好跑一半,以此来达到找到中间节点的目的。

2.判断链表中的环

还是把链表比作一条跑道,链表中有环,那么这条跑道就是一条圆环跑道,在一条圆环跑道中,两个人有速度差,那么迟早两个人会相遇,只要相遇那么就说明有环。

3.删除倒数第n个节点

删除倒数第n个节点,那就等于是要我们先找出待删除元素前一个元素,也就是第n-1个节点。聪明的你肯定发现了,我们又把这个问题转化为找链表上的某个节点的问题了

#include<string>
#include<iostream>
#include<stdlib.h>
#include<stdio.h>
using namespace std;
typedef struct student
{
	int num;
	struct student *pnext;
}STU;
STU* Greatlist1()
{
	STU *pstu1 = (STU*)malloc(sizeof(STU));
	pstu1->pnext = NULL;
	return pstu1;
}
STU* GreastList2()
{
	STU *pstu2 = (STU*)malloc(sizeof(STU));
	pstu2->pnext = NULL;
	return pstu2;
}
void AddNode1(STU*p)//尾插法
{
	int num_1;
	cout << "输入尾插法要添加的节点数" << endl;
	cin >> num_1;
	STU*pnew = NULL;
	for (int i = 0,j=0; i < num_1; i++,j++)
	{
		pnew = (STU*)malloc(sizeof(STU));
		pnew->num = j;
		pnew->pnext = NULL;
		p->pnext = pnew;
		p = p->pnext;
	}
}
void AddNode2(STU*p)//头插法
{
	int num1;
	cout << "输入头插法要添加的节点数" << endl;
	cin >> num1;
	STU*pnew1 = NULL;
	for (int i = 0, j = 0; i < num1; i++, j++)
	{
		pnew1 = (STU*)malloc(sizeof(STU));
		pnew1->num = j;
		pnew1->pnext = p->pnext;
		p->pnext = pnew1;
	}
}
void Print1(STU*p)
{
	while (p->pnext != NULL)
	{
		cout << p->pnext->num<<"   ";
		p = p->pnext;
	}
	cout << endl;
}
void Print2(STU*p)
{
	while (p->pnext != NULL)
	{
		cout << p->pnext->num<<"  ";
		p = p->pnext;
	}
	cout << endl;
}
//快慢指针
void SearchAddNode1(STU*p)
{
	STU*fast = p;
	STU*slow = p;
	int count = 0, ss = 0;
	while (fast )
	{
		if (fast->pnext == NULL)
		{
			ss = 1;//1为偶数
			break;
		}
		count++;
		fast = fast->pnext->pnext;
		slow = slow->pnext;
	}
	if (count==0)
		cout << "List1没有元素" << endl;
	else
	{
		if (ss == 0)
		{
			cout << "平均值在当前位数为:" << count << "   " << "List1中点元素平均值为: " << slow->num << endl;
		}
		else
		{
			cout << "平均值在当前位数为:" << count<<"和"<< count+1 <<"之间"<< "  ";
			cout << "List1中点元素平均值为: " << (float)(slow->num + slow->pnext->num) / 2 << endl;
		}
	}
}
void SearchAddNode2(STU*p)
{
	STU*fast = p;
	STU*slow = p;
	int count = 0, ss = 0;
	while (fast)
	{
		if (fast->pnext == NULL)
		{
			ss = 1;//1为偶数
			break;
		}
		count++;
		fast = fast->pnext->pnext;
		slow = slow->pnext;
	}
	if (count == 0)
		cout << "List2没有元素" << endl;
	else
	{
		if (ss == 0)
		{
			cout << "平均值在当前位数为:" << count << "   " << "List2中点元素平均值为: " << slow->num << endl;
		}
		else
		{
			cout << "平均值在当前位数为:" << count<<"和"<< count-1 <<"之间" << "  ";
			cout << "List2中点元素平均值为: " << (float)(slow->num + slow->pnext->num) / 2 << endl;
		}
	}
}
int main()
{
	STU*p1 = Greatlist1();
	AddNode1(p1);
	Print1(p1);
	SearchAddNode1(p1);
	STU*p2 = GreastList2();
	AddNode2(p2);
	Print2(p2);
	SearchAddNode2(p2);
	return 0;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值