快慢指针和链表原地反转

1,制作环型链表

2。检測链表中是否存在环(參考文章

3。计算链表中环的长度

4, 计算链表中环起始的位置

5,推断一个链表是否存在回文,要求O(n)时间和O(1)空间的复杂度(推断链表是否是回文,要求O(n)时间。O(1)空间

6。计算链表中间位置

7,链表原地反转(链表原地反转

8,測试code

#include <iostream>
using namespace std;
/*
	@1: detect if there is a circule in a list -> detect_circule_exist
	@2: calculate the circule length in the list -> give_circ_len
	@3: locate the place where the circule starts -> locate_circ_place
	@4: detect if the list is palindrome -> time:o(n) and space:o(1)
*/
/*
	struct simple linked list
*/
struct item
{
	int n;
	struct item *next;
};
class iter {
	struct item *head;
	int circ_len;
public:
	void insert(int i);
	bool remove(int i);
	iter(){this->circ_len = 0;this->head = new(struct item);this->head->next = NULL;}
	bool create_circule(int i);
	void remove_circule();
	bool detect_circule_exist();
	int give_circ_len();
	int locate_circ_place();
	bool detect_palindrome();
	void display();
	~iter();
};
void iter::insert(int i) {
	struct item *cur;
	struct item *add_item = new(struct item);
	add_item->n = i;
	add_item->next = NULL;
	/* insert at tail */
	cur = this->head;
	while(cur->next) {
		cur = cur->next;
	}
	cur->next = add_item;
	cout << add_item <<endl;
}
bool iter::remove(int i)
{
	struct item *cur = this->head->next, *prev = this->head;
	while (cur) {
		if (cur->n == i) {
			prev->next = cur->next;
			return true;
		} else {
			cur = cur->next;
			prev = prev->next;
		}
	}
	return false;
}
void iter::display()
{
	struct item *cur = this->head->next;
	while (cur){
		cout << cur->n << " -> ";
		cur = cur->next;
	}
	cout <<"end" << endl;
}

/* create a circult at value: i, if not i exist return false*/
bool iter::create_circule(int i)
{
	struct item *cur = this->head;
	struct item *find = NULL;
	while (cur->next){
		cur = cur->next;
		if (cur->n == i) {
			find = cur;
		}
	}
	if (find) {
		cur->next = find;
		return true;
	} else
		return false;
}
/* detect if exist a circule in the linked list */
bool iter:: detect_circule_exist()
{
	/*quick and slow point to the first element of the linked list*/
	struct item *quick, *slow, *mark;
	bool find = false;
	slow = this->head->next;
	quick = this->head->next->next;

	while (quick && slow) {
		if (!find) {
			if (quick == slow) {
				find = true;
				mark = slow;
				slow = slow->next;
				this->circ_len++;
			} else {
				if (!quick->next || !quick->next->next)
					break;
				if (!slow->next)
					break;
				quick = quick->next->next;
				slow = slow->next;
			}
		} else {
			if (mark == slow) {
				return true;
			} else {
				slow = slow->next;
				this->circ_len++;
			}
		}
	}
	find = false;
	return find;

}
int iter:: give_circ_len()
{
	this->detect_circule_exist();
	return this->circ_len;
}
/* cal the len of non circule at the linked list */
int iter:: locate_circ_place()
{
	if (this->detect_circule_exist()) {
		struct item *quick, *slow;
		int i = this->circ_len;
		slow = this->head->next;
		quick = this->head->next;

		while (quick && i--) {
			quick = quick->next;
		}
		i = 0;
		while (quick && slow) {
			if (quick == slow) {
				return i;
			} else {
				i++;
				quick = quick->next;
				slow = slow->next;
			}
		}

	} else {
		return 0;
	}
}
void iter:: remove_circule()
{
	struct item *tail = this->head;
	struct item *mark;
	int i = this->locate_circ_place() + 1;
	while (tail->next && i--){
		tail = tail->next;
	}
	mark = tail;
	while (tail) {
			if (tail->next == mark) {
			tail->next = NULL;
			return;
		} else {
			tail = tail->next;
		}
	}
}
bool iter:: detect_palindrome()
{
	struct item *quick, *slow;
	/*first find the middle place of the linked list by quick and slow pointer*/
	slow = this->head->next;
	quick = this->head->next->next;
	while (slow) {
		struct item *mark;
		slow = slow->next;
		quick = quick->next->next;
		if (!quick) {
			/*reverse the linked list at the place*/
			mark = slow;
			quick = slow->next->next; /*q*/
			slow = slow->next; /*p*/
			struct item *temp;
			while (quick) {
				temp = quick->next;
				quick->next = slow;
				slow = quick;
				quick = temp;
			}
			mark->next->next = NULL;
			mark->next = slow;
			slow = this->head->next;
			mark = mark->next;
			while (slow && mark) {
				//cout << "odd first part: "<< slow->n << "addr:"  << slow << "second part: " << mark->n << "addr:" << mark <<endl;
				if (slow->n != mark->n)
					return false;
				else {
					slow = slow->next;
					mark = mark->next;
				}
			}
			return true;
		}
		if (!quick->next) {
			/*reverse the linked list at the place*/
			mark = slow;
			quick = slow->next->next; /*q*/
			slow = slow->next; /*p*/
			struct item *temp;
			while (quick) {
				temp = quick->next;
				quick->next = slow;
				slow = quick;
				quick = temp;
			}
			mark->next->next = NULL;
			mark->next = slow;
			slow = this->head->next;
			mark = mark->next;
			while (slow && mark) {
				//cout << "even first part: "<< slow->n << "addr:"  << slow << "second part: " << mark->n << "addr:" << mark <<endl;
				if (slow->n != mark->n)
					return false;
				else {
					slow = slow->next;
					mark = mark->next;
				}
			}
			return true;
		}
	}
}
iter::~iter()
{
	struct item *cur = this->head->next;
	if (this->detect_circule_exist())
		this->remove_circule();
	while (cur){
		struct item *temp = cur;
		cur = cur->next;
		delete temp;
		//cout <<"delete" << temp<< endl;
	}
	delete this->head;

}
int main()
{
	class iter myiter;
	/*
	for (int i = 0; i < 10; i++) {
		myiter.insert(i);
	}
	myiter.create_circule(2);

	if (myiter.detect_circule_exist())
		cout << "detect circule exist and circ len" << myiter.give_circ_len()<< endl;
	else
		cout << "no detect circule exist" <<endl;
 	cout << "circ point index" << myiter.locate_circ_place() <<endl;

 	myiter.remove_circule();
 	myiter.display();
 	*/
 	/*
 	myiter.insert(1);
 	myiter.insert(2);
 	myiter.insert(3);
 	myiter.insert(3);
 	myiter.insert(2);
 	myiter.insert(1);
 	if (myiter.detect_palindrome())
 		cout << "even detect palindrome" <<endl;
 	else
 		cout << "even no detect palindrome" <<endl;
 	*/
 	myiter.insert(1);
 	myiter.insert(2);
 	myiter.insert(3);
 	myiter.insert(2);
 	myiter.insert(1);
 	if (myiter.detect_palindrome())
 		cout << "odd detect palindrome" <<endl;
 	else
 		cout << "odd no detect palindrome" <<endl;
 	return 1;
}
时间: 2024-10-02 08:10:24

快慢指针和链表原地反转的相关文章

Alogorim:链表原地反转Demo

现在就是Qt开发和给师弟师妹讲下数据结构吧,感觉还挺漫长的,上个Qt帖子等我把成品做出来再更. 1 //Convert_plug.h 2 3 #ifndef CONVERT 4 #define CONVERT 5 6 #define MAX 81 7 typedef char NmaeType; 8 typedef struct _name_list 9 { 10 NmaeType name[81]; 11 struct _name_list *next; 12 }Name_List; 13 1

为什么用快慢指针找链表的环,快指针和慢指针一定会相遇

https://www.zhihu.com/question/23208893 首先相遇不是操场跑圈,快的能追上慢的,这还用问吗,肯定能追上.而楼主问的是一个人是跳1个格子,另一个跳2个格子,会不会每次要相遇的时候,快的都会跳过慢的那个,从而不会相遇在一个格子.(重点是为什么一定会相遇在一个格子) 通俗点可以理解为他们的相对速度只差一个格子,快的只能一个一个格子的去追慢的,必然在一个格子相遇! 如果没看懂,看下面的详细.一次跳2个与一次跳一个格子的追上之后,是一定会在一个格子遇到的.因为在即将追

一文学会链表快慢指针解题技巧

前言 上文 我们详细地学习了链表的基本概念,优缺点,也带大家一步步由浅入深地学习了链表的翻转技巧,这一篇我们来看看链表的另一个解题技巧:快慢指针. 快慢指针在面试中出现的概率也很大,也是务必要掌握的一个要点,本文总结了市面上常见的快慢指针解题技巧,相信看完后此类问题能手到擒来.本文将详细讲述如何用快慢指针解决以下两大类问题 寻找/删除第 K 个结点 有关链表环问题的相关解法 寻找/删除第 K 个结点 小试牛刀之一 LeetCode 876:给定一个带有头结点 head 的非空单链表,返回链表的中

快慢指针及应用【转】

快慢指针中的快慢指的是移动的步长,即每次向前移动速度的快慢.例如可以让快指针每次沿链表向前移动2,慢指针每次向前移动1次. 判断单链表是否为循环链表 让快慢指针从链表头开始遍历,快指针向前移动两个位置,慢指针向前移动一个位置;如果快指针到达NULL,说明链表以NULL为结尾,不是循环链表.如果 快指针追上慢指针,则表示出现了循环. fast=slow=head; fast=fast->next->next; slow=slow->next; while(true){ if (fast==

快慢指针的应用

1.判断单链表是否存在环 1 * Definition for singly-linked list. 2 * public class ListNode { 3 * public int val; 4 * public ListNode next; 5 * public ListNode(int x) { 6 * val = x; 7 * next = null; 8 * } 9 * } 10 */ 11 public class Solution { 12 public bool HasCy

算法复习:双指针(对撞指针、快慢指针)

一.快慢指针: leedcode 142. 环形链表 II 快慢指针的思想是设置慢指针slow和快指针fast,slow每次走一步,fast每次走两步,如果有环fast指针和slow指针必然相遇,相遇时 定义新的指针p从head开始和slow从当前位置起每次都走一步,直到相遇,相遇的位置就是环的入口. class Solution { public: ListNode *detectCycle(ListNode *head) { int lable=0; struct ListNode *slo

快慢指针原理--快速找到未知长度单链表的中间节点

package com.java.dataStruct; //节点类 public class Node<E> { E item; Node next; public Node(){ } public Node(E element){ this.item = element; } public Node(E element, Node next){ this.item = element; this.next = next; } } Node p1,r1; Node L1 = new Node

求单链表的中间节点,用快慢指针

? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Node* findMid(Node* &head) {     if(head == NULL||head->next == NULL)         return head;          Node* p = head;     Node* q = head;     while(q->next->next&&(q = q->next))     {         p = p-

reorder-list——链表、快慢指针、逆转链表、链表合并

Given a singly linked list L: L0→L1→-→Ln-1→Ln,reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→- You must do this in-place without altering the nodes' values. For example,Given{1,2,3,4}, reorder it to{1,4,2,3}. 由于链表尾端不干净,导致fast->next!=NULL&&fast->next-&