题目:输入一个链表的头结点,从尾到头反过来打印每个结点的值。
单链表的实现:
1、linklist.h
#ifndef _LINKLIST_H_
#define _LINKLIST_H_
typedef int Elem_Type;
typedef struct LNode
{
Elem_Type data;
struct LNode* next;
}LNode,*LinkList;
void init_list(LinkList* phead);
void insert_tail(LinkList* phead,Elem_Type val);
void insert_head(LinkList* phead,Elem_Type val);
void remove_node(LinkList* phead,Elem_Type val);
void clear_list(LinkList* phead);
void destroy_list(LinkList* phead);
void show_list(LinkList* phead);
bool is_Empty(LinkList* phead);
int list_size(LinkList* phead);
#endif
2、linklist.cpp
#include "linklist.h"
#include <cassert>
#include <iostream>
#include <stack>
using namespace std;
//初始化单链表
void init_list(LinkList* phead)
{
assert(phead != NULL);
(*phead) = new LNode;
(*phead)->next = NULL;
}
//尾插
void insert_tail(LinkList* phead, Elem_Type val)
{
assert(phead != NULL);
LNode* p = *phead;
if (NULL == p)
{
return;
}
while (p->next != NULL)
{
p = p->next;
}
LNode* newNode = new LNode;
newNode->data = val;
newNode->next = NULL;
p->next = newNode;
}
//头插
void insert_head(LinkList* phead, Elem_Type val)
{
assert(phead != NULL);
LNode* p = *phead;
if (NULL == p)
{
return;
}
LNode* newNode = new LNode;
newNode->data = val;
newNode->next = p->next;
p->next = newNode;
}
//删除结点
void remove_node(LinkList* phead, Elem_Type val)
{
assert(phead != NULL);
LNode* p = *phead;
if (NULL == p)
{
return;
}
LNode* ppre = p;
LNode* pcur = p->next;
while (pcur != NULL)
{
if (pcur->data == val)
{
ppre->next = pcur->next;
delete pcur;
pcur = ppre->next;
}
else
{
ppre = pcur;
pcur = ppre->next;
}
}
}
//清空单链表
void clear_list(LinkList* phead)
{
assert(phead != NULL);
LNode* p = *phead;
if (p == NULL)
{
return;
}
LNode* ptmp = p->next;
while (ptmp != NULL)
{
p = ptmp->next;
delete ptmp;
ptmp = p;
}
(*phead)->next = NULL;
}
//销毁链表
void destroy_list(LinkList* phead)
{
assert(phead != NULL);
LNode* p = *phead;
LNode* ptmp;
while (p != NULL)
{
ptmp = p->next;
delete p;
p = ptmp;
}
*phead = NULL;
}
//打印单链表
void show_list(LinkList* phead)
{
assert(phead != NULL);
LNode* p = *phead;
if (p == NULL)
{
return;
}
while (p->next != NULL)
{
cout << p->next->data << " ";
p = p->next;
}
cout << endl;
}
//判空
bool is_Empty(LinkList* phead)
{
assert(phead != NULL);
LNode* p = *phead;
if (p == NULL)
{
return true;
}
return p->next == NULL;
}
//单链表的大小
int list_size(LinkList* phead)
{
assert(phead != NULL);
LNode* p = *phead;
if (p == NULL)
{
return 0;
}
int i = 0;
while (p->next != NULL)
{
++i;
p = p->next;
}
return i;
}
3、test_linklist.cpp
#include "linklist.h"
#include <iostream>
using namespace std;
int main(int argc, char* argv[])
{
LinkList list;
init_list(&list);
insert_tail(&list,5);
insert_tail(&list,10);
insert_tail(&list,14);
insert_head(&list,8);
show_list(&list);
//remove_node(&list,5);
//show_list(&list);
//cout << is_Empty(&list) << endl;
//cout << list_size(&list) << endl;
// clear_list(&list);
// destroy_list(&list);
// cout << list_size(&list) << endl;
printListReversely_iteratively(list);
printListReversely_recursively(list);
cout << endl;
insert_head(NULL,5);
return 0;
}
解题思路
思路一:遍历单链表的顺序是从头到尾的顺序,可输出的顺序却是从尾到头。也就是说第一个遍历到的结点最后一个输出,而最后一个遍历到的结点是第一个输出。这就是典型的“后进先出”,可以用栈实现这种顺序。
//非递归逆序打印链表
void printListReversely_iteratively(LinkList phead)
{
assert(phead != NULL);
stack<LNode*> sta;
LNode* p = phead->next;
while (p != NULL)
{
sta.push(p);
p = p->next;
}
while (!sta.empty())
{
LNode* node = sta.top();
cout << node->data << " ";
sta.pop();
}
cout << endl;
}
思路二:既然可以用栈实现,而递归在本质上就是一个栈结构,因此也可以用递归来实现。
//函数声明
void printList(LNode* p);
//递归逆序打印链表
void printListReversely_recursively(LinkList phead)
{
assert(phead != NULL);
printList(phead->next);
}
//逆序打印链表
void printList(LNode* p)
{
if (p != NULL)
{
if (p->next != NULL)
{
printList(p->next);
}
cout << p->data << " ";
}
}