K个一组翻转链表

2022/1/13 23:06:57

本文主要是介绍K个一组翻转链表,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

题目

一个链表,每个K个节点一组翻转,返回翻转后的链表
例如
链表为{1, 2, 3, 4, 5 }
K = 2
翻转后 {2, 1, 4, 3, 5}

结果

list: 1, 4, 7, 10, 56, 23, 23, 2, 87
K = 3
reverse:7, 4, 1, 23, 56, 10, 87, 2, 23
list: 7, 4, 1, 23, 56, 10, 87, 2, 23
K = 2
reverse: 4, 7, 23, 1, 10, 56, 2, 87, 23

代码

#include <iostream>
#include <string>
#include <sstream>
#include <vector>
#include <time.h>
#include <assert.h>
#include <random>

class EList {
public:

	typedef int value_type;

	struct ListNode {
		value_type value = 0;
		ListNode* prev = nullptr;
		ListNode* next = nullptr;
	};

	ListNode* first_node = nullptr;
	ListNode* last_node = nullptr;
	std::size_t count;

	EList() = default;

	EList(std::size_t count) {
		for (std::size_t i = 0; i < count; ++i)
			this->push_back(0);
	}

	EList(std::initializer_list<value_type> lst) {
		this->count = lst.size();
		if (lst.size() > 0) {
			auto it = lst.begin();
			this->first_node = new ListNode{ *it, nullptr, nullptr };
			ListNode* cur = this->first_node;
			++it;
			for (; it != lst.end(); ++it) {
				ListNode* next = new ListNode{ *it, cur, nullptr };
				cur->next = next;
				cur = next;
			}
			last_node = cur;
		}
	}


	EList(const EList& lst) {
		clone(lst);
	}

	EList& operator=(const EList& e) {
		clone(e);
		return *this;
	}

	void clone(const EList& lst) {
		ListNode* other_cur = lst.first_node;
		ListNode* pre = nullptr;
		ListNode* cur = nullptr;
		while (other_cur) {
			cur = new ListNode{ other_cur->value, pre, nullptr };
			if (pre) {
				pre->next = cur;
			}
			else {
				first_node = cur;
			}
			pre = cur;
			other_cur = other_cur->next;
		}
		this->count = lst.count;
		last_node = cur;
	}

	~EList() {
		ListNode* cur = first_node;
		while (cur) {
			ListNode* temp = cur;
			cur = cur->next;
			delete temp;
		}
		first_node = nullptr;
		last_node = nullptr;
		count = 0;
	}

	void push_back(value_type v) {
		ListNode* node = new ListNode{ v, last_node, nullptr };
		if (last_node) {
			// 有数据的话
			last_node->next = node;
			last_node = node;
		}
		else {
			// 没有数据的话
			last_node = node;
			first_node = node;
		}
		++count;
	}

	std::string to_string() const {
		std::stringstream strstr;
		ListNode* cur = this->first_node;
		while (cur != last_node) {
			strstr << cur->value << ", ";
			cur = cur->next;
		}
		if (last_node)
			strstr << last_node->value;

		return strstr.str();
	}

	static EList create_random_list(std::size_t count) {
		std::size_t cur = 0;
		std::default_random_engine e(count);
		EList temp;
		for (std::size_t i = 0; i < count; ++i) {
			std::uniform_int_distribution<value_type> u(0, 100);
			cur += u(e);
			temp.push_back(cur);
		}
		return temp;
	}

	void switch_node(ListNode* n1, ListNode* n2) {
		if (n1 == n2)
			return;

		if (n1->next == n2) {
			n1->next = n2->next;
			if (n2->next) {
				n2->next->prev = n1;
			}
			n2->prev = n1->prev;
			if (n1->prev) {
				n1->prev->next = n2;
			}
			n2->next = n1;
			n1->prev = n2;
		}
		else if (n2->next == n1) {
			n2->next = n1->next;
			if (n1->next) {
				n1->next->prev = n2;
			}
			n1->prev = n2->prev;
			if (n2->prev) {
				n2->prev->next = n1;
			}
			n1->next = n2;
			n2->prev = n1;
		}
		else {
			// 完全不相邻,共影响6个节点
			ListNode* n1_next = n1->next;
			ListNode* n2_next = n2->next;
			n2->next = n1_next;
			n1->next = n2_next;
			if (n1_next)
			{
				n1_next->prev = n2;
			}
			if (n2_next) {
				n2_next->prev = n1;
			}

			ListNode* n1_prev = n1->prev;
			ListNode* n2_prev = n2->prev;
			n1->prev = n2->prev;
			n2->prev = n1->prev;
			if (n1_prev) n1_prev->next = n2;
			if (n2_prev) n2_prev->next = n1;
		}

		if (n1->prev == nullptr)
			this->first_node = n1;
		else if (n2->prev == nullptr)
			this->first_node = n2;

		if (n2->next == nullptr)
			this->last_node = n2;
		else if (n1->next == nullptr)
			this->last_node = n1;
	}

	// 反转链
	void reverse(int every_count) {
		ListNode* start_node = this->first_node;
		for (int cur = 0; cur < this->count; cur += every_count) {
			// 先找到
			ListNode* last_node = start_node;

			for (int i = 0; i < every_count - 1; ++i) {
				last_node = last_node->next;
			}

			if (last_node == nullptr)
				return;
			//std::cout << "start " << start_node->value << " last: " << last_node->value << ", index:" << cur << std::endl;

			ListNode* next_start = last_node->next;

			ListNode* cur_start = start_node;
			ListNode* cur_last = last_node;
			// 开始交换
			while (cur_start != cur_last) {
				ListNode* temp_start = cur_start->next;
				ListNode* temp_last = cur_last->prev;;
				if (cur_start->next == cur_last) {
					this->switch_node(cur_start, cur_last);
					break;
				}
				else {
					this->switch_node(cur_last, cur_start);
				}
				cur_start = temp_start;
				cur_last = temp_last;

			}
			//std::cout << "cur list:" << this->to_string() << std::endl;
			start_node = next_start;
		}
	}

};


void test_switch_list() {
	EList lst1 = {
		{1, 4, 7, 10, 56, 23, 23, 2, 87 }
	};
	std::cout << "list: " << lst1.to_string() << std::endl;
	std::cout << "K = 3" << std::endl;
	lst1.reverse(3);
	std::cout << "reverse:" << lst1.to_string() << std::endl;

	EList lst2 = {
	{1, 4, 7, 10, 56, 23, 23, 2, 87 }
	};
	std::cout << "list: " << lst1.to_string() << std::endl;
	std::cout << "K = 2" << std::endl;
	lst1.reverse(2);
	std::cout << "reverse: " << lst1.to_string() << std::endl;

}


这篇关于K个一组翻转链表的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程