您的位置:首页 > 职场人生

《剑指offer》【面试题5:从尾到头打印链表】

2018-03-24 16:32 746 查看
面试题五:从尾到头打印链表

链表是一种频繁被提及的数据结构,它是通过指针把若干个结点连接成链状的一种数据结构。由于链表的操作是通过指针来实现的,所以在这里指针的正常使用也是面试官所容易提及的一个考点。

题目:  输入一个链表的头结点,从尾到头反过来打印出每个节点的值;
分析:当遇见这种题的时候,瞬间感觉自己对于链表的所有认识全部给抛了出来,什么双向链表,循环链表了等等,但是额外的想这些只会为你的大脑提供更多的负担,解决确实可以解决,但是这样会使链表的结构发现相应的改变。或许有的会想到单链表不是只能从前向后遍历,倒着从后往前遍历不是不可以吗,面试题就是抓住了这点,所以需要你灵活的去巧妙的进行解决这个问题。这里我们是利用了另一种数据结构---栈的特性---先进后出,我们通过先进后出这个特点,把链表中的所有数据结点从前向后遍历,并依次的压入栈中,当遍历完整个链表以后,再从栈顶开始逐个的弹出(出栈),这样我们就实现了链表的从尾到头打印链表了。图解:


相应的栈和链表类的部分功能的实现 :#include <iostream&
4000
gt;
#include <assert.h>
using namespace std;

//栈
class CDstack
{
public:
CDstack()
{
//cout<<"CDstack()"<<endl;
_elem = new int[INITSIZE];
_top = 0;
_topsize = INITSIZE;
}
~CDstack()
{
delete[]_elem;
}
bool isfull()//判满
{
return _top == _topsize;
}
bool isempty()//判空
{
return _top == 0;
}
void resize()//扩容
{
int *newelem = new int[_topsize*2];
for (int i = 0; i<_top; i++)
{
newelem[i] = _elem[i];
}
delete []_elem;
_elem = newelem;
_topsize = _topsize*2;
}
void push(int val)
{
if (isfull())
{
resize();
}
_elem[_top++] = val;
}
void pop(int *rtval)//获取值且删除
{
if (!isempty())
{
*rtval = _elem[--_top];
}
}
void show()
{
for (int i = 0; i<_top;i++)
{
cout<<_elem[i]<<" ";
}
cout<<endl;
}
int max_size()
{
return _topsize;
}
int data_size()
{
return _top;
}
private:
enum{INITSIZE = 20};//初始格子大小
int *_elem;
int _top;//栈顶指针,标记当前可以存放数据的下标
int _topsize;//总格子数
};

//结点
class Node
{
public:
Node()
{
pnext = NULL;
}

private:
int data;
Node *pnext;
friend class CList;
};

//链表
class CList
{
public:
CList()
{
phead = new Node();
//cout<<"CList()"<<endl;
}

~CList()
{
Node* p = phead;
while(phead->pnext != NULL)
{
p = phead->pnext;
phead->pnext = p->pnext;
delete p;
}
delete phead;
}

void insert(int val)
{
Node *p = new Node();
p->data = val;
p->pnext = phead->pnext;
phead->pnext = p;
}
//获取头结点后面的结点的值,并删除这个结点
void gethead_data(int *val)
{
Node *p = phead->pnext;
*val = p->data;
phead->pnext = p->pnext;
delete p;
}
bool isempty()
{
return phead->pnext == NULL;
}
void show()
{
Node *p = phead->pnext;
while(p != NULL)
{
cout<<p->data<<" ";
p = p->pnext;
}
cout<<endl;
}

private:
Node* phead;
};
面试题五代码详解://面试题五:
void last_front_ShowList(CList *phead)
{
assert(phead != NULL);
CDstack stack1;
while(!phead->isempty())
{
int val;
phead->gethead_data(&val);
stack1.push(val);
}

while(!stack1.isempty())
{
int retval;
stack1.pop(&retval);
cout<<retval<<" ";
}
cout<<endl;
}
int main()
{
//-------------------------------面试题五测试用例:------------------------------------

//测试链表有多个结点的链表
CList list1;
for (int i = 10; i>0; i--)
{
list1.insert(i);
}
//list1.show();
cout<<"链表有多个结点的链表"<<endl;
last_front_ShowList(&list1);

//测试链表有一个结点的链表
CList list2;
list2.insert(15);
cout<<"链表有一个结点的链表"<<endl;
last_front_ShowList(&list2);

//测试链表头结点指针为NULL
CList list3;
cout<<"链表头结点指针为NULL"<<endl;
last_front_ShowList(&list3);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: