剑指Offer-面试题6:从尾到头打印链表

/** 面试题6:从尾到头打印链表
* 题目:输入一个链表的头结点,从尾到头反过来打印出每个节点的值。链表节点定义如下:
* struct ListNode
{
	int m_nKey;
	ListNode* m_pNext;
}
*/

#include<iostream>
#include<stdio.h>
#include<stack>
#include<vector>
using namespace std;

struct ListNode
{
	int m_nKey;
	ListNode* m_pNext;
};
class List
{
private:
	
public:
	List():head(NULL){}
	~List()
	{
		delete head;
		cout << "The list is deleted." << endl;
	}
	ListNode* head;
	int Size();						// 链表长度
	bool IsEmpty();					// 是否为空
	void PrintList();				// 打印链表
	void InsertHead(int value);		// 插入到最前
	void Insert(int pos, int value);	// 在指定位置插入
	void InsertTail(int value);		// 插入到最后
	int Search(int value);			// 查找指定元素的位置
	void Update(int pos, int value);		// 更新指定位置的值
	int GetValue(int position);			// 获取指定位置的值
	int Erase(int pos);				// 删除指定位置的结点
	void Reverse();			 // 反转链表
	void ClearList();
	vector<int> PrintListFromTailToHead(ListNode* head);

};

// 链表长度
int List::Size()
{
	ListNode* p = head;
	int index = 0;
	while (p)
	{
		index++;
		p = p->m_pNext;
	}
	return index;
}
// 判断链表是否为空
bool List::IsEmpty()
{
	if (List::Size() == 0)
		return false;
	return true;
}
// 打印链表
void List::PrintList()
{
	ListNode*p = head;
	while (p != NULL)
	{
		cout << p->m_nKey << endl;
		p = p->m_pNext;
	}
}

// 在Position位置插入value
void List::Insert(int pos, int value)
{
	if (pos < 0 || pos > List::Size())
	{
		cout << " position error, please check" << endl;
		return;
	}
	ListNode* s = new ListNode();
	s->m_nKey = value;
	ListNode* p = head;
	if (head == NULL)
		head = s;
	else
	{
		if (pos == 0)
		{
			s->m_pNext = p;
			head = s;
		}
		else
		{
			int index = 0;
			while (index != pos - 1)
			{
				p = p->m_pNext;
				index++;
			}
			s->m_pNext = p->m_pNext;
			p->m_pNext = s;
		}
	}
	if (pos == 0)
		cout << "Insert " << value << "at the first." << endl;
	else if (pos == List::Size())
		cout << "Insert " << value << "at the tail." << endl;
	else
		cout << "Insert " << value << "at postion " << pos << endl;

}

// 头部插入
void List::InsertHead(int value)
{
	List::Insert(0, value);
}

// 尾部插入
void List::InsertTail(int value)
{
	List::Insert(List::Size(), value);
}

// 搜索数据value,并返回位置
int List::Search(int value)
{
	ListNode* p = head;
	int index = 0;
	while (p != NULL && p->m_nKey != value)
	{
		index++;
		p = p->m_pNext;
	}
	if (p = NULL)
	{
		cout << "the value is not in the list, please check." << endl;
		return -1;
	}
	else
	{
		cout << value << " at position " << index << endl;
		return index;
	}
}
// 将Position位置的数据 更新为value
void List::Update(int position, int value)
{
	if (position < 0 || position > List::Size())
	{
		cout << "position error, please check." << endl;
		return;
	}
	ListNode* p = head;
	int index = 0;
	while (index != position)
	{
		p = p->m_pNext;
		index++;
	}
	p->m_nKey = value;
	cout << "Update " << value << "at position " << position << endl;
}

// 删除position位置的数据,并返回
int List::Erase(int position)
{
	ListNode* p = head;
	int res = List::GetValue(position);
	if (position < 0 || position > List::Size())
	{
		cout << "position error, please check." << endl;
		return -1;
	}
	int index = 0;
	if (position = 0)
	{
		head = p->m_pNext;
		return res;
	}
	else
	{
		while (index != position - 1)
		{
			p = p->m_pNext;
			index++;
		}
		ListNode* temp = p->m_pNext;
		p->m_pNext = temp->m_pNext;
		return res;
	}
	


}

// 反转链表
void List::Reverse()
{
	if (head == NULL || head->m_pNext == NULL)
	{
		return;
	}
	ListNode* prev = head;
	ListNode* cur = head->m_pNext;
	ListNode* temp = head->m_pNext->m_pNext;
	while (cur)
	{
		temp = cur->m_pNext;
		cur->m_pNext = prev;
		prev = cur;
		cur = temp;
	}
	head->m_pNext = NULL;			// 更新末尾元素的指针
	head = prev;					// 更新头结点
	cout << "reverse the list." << endl;
}

// 返回position位置的数据
int List::GetValue(int position)
{
	if (position < 0 || position > List::Size())
	{
		cout << "position error, please check." << endl;
		return -1;
	}
	ListNode* p = head;
	int index = 0;
	while (index != position)
	{
		p = p->m_pNext;
		index++;
	}
	cout << "position " << position << " is" << p->m_nKey << endl;
	return p->m_nKey;
}
// 借助栈实现从尾到头打印链表
vector<int> List::PrintListFromTailToHead(ListNode* head)
{
	stack<int> temp;
	ListNode* p = head;
	while (p != nullptr) 
	{
		temp.push((*p).m_nKey);
		p = p->m_pNext;
	}
	vector<int> res;
	while (!temp.empty())
	{
		res.push_back(temp.top());
		temp.pop();
	}
	return res;
}


int main()
{
	
	List list;
	list.InsertHead(7);
	list.Insert(1, 1);
	list.Insert(2, 2);
	list.Insert(3, 3);
	list.Insert(4, 4);
	cout << "=================打印链表==============" << endl;
	list.PrintList();
	cout << "方法一:改变了链表的结构===========反转链表=================" << endl;
	list.Reverse();
	list.PrintList();
	cout << "方法二:不改变链表结构=============反转链表=================" << endl;
	vector<int>result;
	ListNode* p = list.head;
	result = list.PrintListFromTailToHead(p);
	for (auto& it : result)
	{
		cout << it << "    ";
	}
	cout << endl;


	system("pause");
}

void PrintListReversingly_Iteratively(ListNode* pHead)
{
	std::stack<ListNode*> nodes;
	ListNode* pNode = pHead;
	while (pNode != nullptr)
	{
		nodes.push(pNode);
		pNode = pNode->m_pNext;
	}
	while (!nodes.empty())
	{
		pNode = nodes.top();
		cout << pNode->m_nKey;
		nodes.pop();
	}
}

void PrintListReversingly_Recursively(ListNode* pHead)
{
	if (pHead != nullptr)
	{
		if (pHead->m_pNext != nullptr)
		{
			PrintListReversingly_Recursively(pHead->m_pNext);
		}
		cout << pHead->m_pNext;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
信息数据从传统到当代,是一直在变革当中,突如其来的互联网让传统的信息管理看到了革命性的曙光,因为传统信息管理从时效性,还是安全性,还是可操作性等各个方面来讲,遇到了互联网时代才发现能补上自古以来的短板,有效的提升管理的效率和业务水平。传统的管理模式,时间越久管理的内容越多,也需要更多的人来对数据进行整理,并且数据的汇总查询方面效率也是极其的低下,并且数据安全方面永远不会保证安全性能。结合数据内容管理的种种缺点,在互联网时代都可以得到有效的补充。结合先进的互联网技术,开发符合需求的软件,让数据内容管理不管是从录入的及时性,查看的及时性还是汇总分析的及时性,都能让正确率达到最高,管理更加的科学和便捷。本次开发的医院后台管理系统实现了病房管理、病例管理、处方管理、字典管理、公告信息管理、患者管理、药品管理、医生管理、预约医生管理、住院管理、管理员管理等功能。系统用到了关系型数据库中王者MySql作为系统的数据库,有效的对数据进行安全的存储,有效的备份,对数据可靠性方面得到了保证。并且程序也具备程序需求的所有功能,使得操作性还是安全性都大大提高,让医院后台管理系统更能从理念走到现实,确确实实的让人们提升信息处理效率。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值