对顺序表与链表难题的实现

该文主要介绍了使用C++实现链表的各种操作,包括插入节点、删除特定位置节点、检测快乐数、旋转链表以及找到循环链表的起始节点。快乐数是指经过数位平方和的迭代最终达到1的数字。旋转链表函数实现了将链表向右移动指定位置的功能,而删除函数则能删除链表的倒数第n个节点。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include<iostream>
using namespace std;
class ListNode
{
public:
	int data;
	ListNode* next;
	ListNode() {
		next = NULL;
	}
};
class LinkList {
public:
	int len;
	ListNode* head;
	LinkList() {
		head = NULL;
		len = 0;
	}
	void insert(int index,int num) {
		ListNode* p = new ListNode();
		p = head;
		for (int i = 0; i < index; i++) {
			p = p->next;
		}
		ListNode* node;
		node->data = num;
		node->next = p->next;
		p->next = node;
		len++;
	}
	void del(int index) {
		ListNode* p = head;
		for (int i = 0; i < index; i++) {
			p = p->next;
		}
		ListNode* q = p->next;
		p = p->next->next;
		delete q;
		len--;
	}
};
class Solution {
public:
	//什么是快乐数
	//一个数字能够变换到1就是快乐数
	//每个位置的数的平方和即为他的变换方式
	//把所有数看成一个个节点,把最后的1看作空指针
	//所以要想走到空指针只需要判断能不能走到NULL的位置
	int getNext(int x) {
		int y;
		int d;
		while (x) {
			d = x % 10;
			y += d * d;//要得到的是平方和
			x /= 10;
		}
		return y;
	}
	bool isHappy(int n) {
		int p = n, q = n;
		//p与q都是表达两个逻辑链表中的两个开头的指针
		//q是跑的快的那个
		while (q != 1) {
			p = getNext(p);
			q = getNext(getNext(q));
			if (p == q && p != 1) {
				//代表进入循环了
				return false;
			}
		}
		return true;
	}
	int getLength(ListNode *head) {
		ListNode* p = head;
		int len;
		while (p) {
			len++;
			p = p->next;
		}
		return len;
	}
	//旋转链表(向右移动k个位置)
	ListNode* rotateRight(ListNode* head,int k) {
		//方法是要找到要被分割的那个节点
		//采用的是等距双指针方法p和q
		//当后面的q移动到空指针的位置是,p指向的节点
		//即为分割的节点
		if (head == NULL) {
			return head;
		}
		int n = getLength(head);
		k %= n;//得到要移动的真实距离
		if (k == 0) {
			return head;
		}
		//head就是head->next
		ListNode* p = head;
		ListNode* q = head;
		for (int i = 0; i <= k; i++) {
			p = p->next;
			//让p指针先往后走k+1步
		}
		while (p) {
			p = p->next;
			q = q->next;
		}
		//得到要分割的位置q
		p = q->next;
		//让p重新指上第二段的头部,
		q->next = NULL;
		q = p;
		while (q->next!=NULL) {
			q = q->next;
		}
		q->next = head;
		return p;
	}
	//删除链表的倒数第你个结点
	ListNode* del(ListNode* head,int last) {
		//要删除哪个结点就要站在被删的前一个结点和当前节点上
		
		//如果要删除第一个节点
		//要把无头链表变成一个有头链表
		ListNode new_head;
		ListNode* p = &new_head;
		ListNode* q = p;
		new_head.next = head;
		for (int i = 0; i <= last; i++) {
			p = p->next;
		}
		while (p) {
			p = p->next;
			q = q->next;
		}
		//q即为要删除的前一个位置
		p = q->next;
		//p为要删除的位置
		q->next = q->next->next;
		delete p;
		return new_head.next;
	}
	//循环链表2,需要找到循环链表的起始位置
	ListNode* detectCycle(ListNode *head) {
		ListNode* p = head, *q = head;
		while (q&&q->next) {
			p = p->next;
			q = q->next->next;
			if (p == q) {
				break;
			}
		}
		if (q == NULL || q->next == NULL) {
			return NULL;
		}
		p = head;
		while (p != q) {
			p = p->next;
			q = q->next;
		}
		return p;//无论是p还是q都是开始的节点
	}
	//反转链表2(对链表中的一部分进行反转)
	ListNode* reverselist(ListNode* head, int left, int right) {
		if (left == 1 && right == 1 ) {
			return head;
		}
		if (left != 1) {
			head->next = reverselist(head->next, left - 1, right - 1);
		}
		else {
			ListNode* tail = head->next;
			ListNode* new_head;
			new_head = reverselist(head->next, left, right - 1);
			head->next = tail->next;
			tail->next = head;
			head = new_head;
		}
		return head; 
	}
	 
};
int main() {
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值