练手小程序2.链表翻转问题

问题1: 给出一个链表 将其翻转,比如 链表1→2→3→4→5→6,翻转后6→5→4→3→2→1
问题2:给出一个链表
和一个数k,将链表进行翻转,比如链表1→2→3→4→5→6,k=2,

            则翻转后2→1→4→3→6→5,若k=3,翻转后3→2→1→6→5→4,若k=4,翻转后4→3→2→1→5→6

考察的知识点:链表的灵活操作

代码如下:

#include "stdafx.h"
#include <iostream>
#include <vector>

//链表结点类型
struct List_Node
{
	int m_num_;
	List_Node *m_next_;
};

//尾插法创建一个单链表
void creat_list_from_tail(List_Node *&p_head)
{	
	std::cout << "尾插法创建一个单链表" << std::endl;

	while (1)
	{
		//新建一个结点
		List_Node *new_node = new List_Node;
		std::cout << "please input a number: ";
		std::cin >> new_node->m_num_;
		new_node->m_next_ = NULL;

		if (-1 == new_node->m_num_)
		{
			return;
		}

		if (NULL == p_head)//链表为空
		{
			p_head = new_node;
		}
		else
		{
			List_Node *p_cur = p_head;

			while (p_cur->m_next_ != NULL)//找到最后一个结点
			{
				p_cur = p_cur->m_next_;
			}

			p_cur->m_next_ = new_node;
		}
	}	
}

//头插法创建一个单链表
void creat_list_from_head(List_Node *&p_head)
{	
	std::cout << "头插法创建一个单链表" << std::endl;
	while (1)
	{
		//新建一个结点
		List_Node *new_node = new List_Node;
		std::cout << "please input a number: ";
		std::cin >> new_node->m_num_;
		new_node->m_next_ = NULL;

		if (-1 == new_node->m_num_)
		{
			return;
		}

		if (NULL == p_head)//链表为空
		{
			p_head = new_node;
		}
		else
		{
			new_node->m_next_ = p_head;
			p_head = new_node;
		}
	}	
}

//打印链表
void print_list(List_Node *p_head)
{
	if (NULL == p_head)
	{
		std::cout << "链表为空!" << std::endl;
		return;
	}

	List_Node *p_cur = p_head;
	std::cout << "链表中的元素为:";

	while (NULL != p_cur)
	{
		std::cout << p_cur->m_num_ << " ";
	    p_cur = p_cur->m_next_;
	}

	std::cout << std::endl;
}

//翻转链表
void reverse_list(List_Node *&list_head)
{
	std::cout << "翻转链表!" << std::endl;

	if (list_head == NULL)
	{
		std::cout << "链表为空!" << std::endl;
		return;
	}

	List_Node *cur_node = list_head;//当前结点
	List_Node *pre_node = NULL;//当前结点的前一个结点
	List_Node *next_node = NULL;//当前结点的下一个结点

    while (cur_node != NULL)
    {
		next_node = cur_node->m_next_;//记录当前结点的下一个结点
        cur_node->m_next_ = pre_node;				
		pre_node = cur_node;
		cur_node = next_node;		
    }

	list_head = pre_node;
}

//将链表list_head按每k个元素切割成若干小的链表存放到list_vec中,且链表内部实现了翻转
void split_list(List_Node *&list_head, int &k, std::vector<List_Node *> &list_vec)
{	
	List_Node *cur_node = list_head;//当前结点
	List_Node *pre_node = NULL;//当前结点的前一个结点
	List_Node *next_node = NULL;//当前结点的下一个结点	
	List_Node *list_tmp = NULL;
	int count = k;

	while (cur_node != NULL && count > 0)
	{
		--count;
		next_node = cur_node->m_next_;//记录当前结点的下一个结点
		cur_node->m_next_ = pre_node;				
		pre_node = cur_node;
		cur_node = next_node;

		if (count == 0 || cur_node == NULL)
		{
			count = k;			
			list_vec.push_back(pre_node);
			pre_node = NULL;
		}
	}
}

//将若干小的链表链接成一个大的链表
void connect_list_vec(std::vector<List_Node *> list_vec, List_Node *&list_head)
{
	List_Node *cur_tail = NULL;
	bool is_first = true;

	for (std::vector<List_Node *>::iterator iter = list_vec.begin();
		iter != list_vec.end(); ++iter)
	{
		if (is_first)
		{
			list_head = *iter;
			cur_tail = *iter;
			is_first = false;
		}
		else
		{
			cur_tail->m_next_ = *iter;			
		}

		while (cur_tail->m_next_ != NULL)
		{
			cur_tail = cur_tail->m_next_;
		}
	}	
}


//翻转链表,指定每K个元素翻转一次
void reverse_list(List_Node *list_head, int &k)
{
	if (list_head == NULL)
	{
		std::cout << "链表为空!" << std::endl;
		return;
	}

	std::cout << "翻转链表!" << std::endl;

	while (1)
	{
		std::cout << "请输入一个数k: ";
		std::cin >> k;	

		if (-1 == k)
		{
			return;
		}

		std::vector<List_Node *> list_vec;
		split_list(list_head, k, list_vec);		
		connect_list_vec(list_vec, list_head);	
		print_list(list_head);
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	List_Node *list_head = NULL;
	creat_list_from_tail(list_head);//创建链表
	print_list(list_head);//打印链表
	int k = 0;
	reverse_list(list_head, k);	//翻转链表	
	system("pause");
	return 0;
}
运行结果:



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值