与带环链表相关的一些操作

与带环链表相关的一些操作

带环链表的概念

显然,环在链表中不能出现在头部和中部,因为这样的话用来实现连接的结点需要两个指针(一个指向后继结点,另一个指向前方的某个结点来形成环),这样会破坏链表原有的结构。所以环只能出现在链表的尾部,只需要将尾结点与之前的任意结点相连即可。为了表示链表的状态,我们用整数pos表示为尾结点连接到链表的位置(索引为0),若pos=-1,则表示链表不带环。

如何处理不带环链表使它变成带环链表

我们所进行的处理要达到这样一个效果,使一个不带环的链表变为一个带环的链表,并且可以指定尾结点连接到链表的位置(pos)。

//思路:先找到尾结点,在找到索引为pos的结点,将二者相连
void ChangeToCircle(LinkList L,int pos)
{
    //pos为-1则不做操作
	if (pos == -1) return;							
	Node* s, * r;
	int i;
    //先找到链表的尾结点
	for (s = L->next; s->next; s = s->next);		
    //再找到索引为pos的结点
	for (r = L, i = 0; i <= pos; i++) r = r->next;	
    //将链表尾结点的尾指针指向索引为pos的结点
	s->next = r;									
}

如何判断链表是否带环

若带环,则返回true,否则返回false。

//思路:快慢指针法,快指针一次走两个结点,慢指针一次走一个结点,若链表带环,那么两者一定会相遇,否则快指针会先一步走完
bool CircleJudge(LinkList L)
{
	Node* fast, * slow;
	//循环条件:不确定链表结点数的奇偶,所以fast和fast->next都有可能是NULL但只要出现一种情况,就说明链表没有环
	for (fast = slow = L; fast != NULL && fast->next != NULL;) {
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow) return true;
	}
	return false;
}

如何计算链表环的长度

//思路:当快慢指针相遇时,快指针所走的路程是慢指针所走路程的两倍,并且快指针比慢指针多走一个环的路程,因此慢指针所走的路程就是链表的长度
int CircleLen(LinkList L)
{
	Node* fast, * slow;
	int len = 0;
	for (fast = slow = L; fast != NULL && fast->next != NULL;) {
		fast = fast->next->next;
		slow = slow->next;
		len++;
		if (fast == slow) return len;
	}
	return -1;
}

如何寻找链表环的入口结点

设从链表头走到环入口需要a步,从环入口走到相遇点需要b步,再从相遇点走回环入口需要c步,那么第一次相遇时慢指针走过(a+b)步,快指针走过(a+b+c+b)步。由a+b+c+b=2(a+b)得a=c。

//思路: 当快慢指针相遇后,将快指针的速度调整到与慢指针一致,然后让任意一个指针从开头跑,另一个指针从相遇点跑,他们会在环的入口点相遇
Node* CirEntrFind(LinkList L)
{
	Node* fast, * slow;
	for (fast = slow = L; fast != NULL && fast->next->next != NULL;) {
		fast = fast->next->next;
		slow = slow->next;
		if (fast == slow) {
			fast = L;
			while (fast != slow) {
				fast = fast->next;
				slow = slow->next;
			}
			return fast;
		}
	}
	return NULL;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值