题目
输入一个链表的头节点,从尾到头反过来打印出来每个节点的值。链表节点定义如下:
struct ListNode
{
int m_nKey;
struct ListNode* m_pNext;
};
思路
栈方法
从尾到头完全符合栈的特性,我们直接拿栈来存储就可以顺利输出。(c语言需要自己构造栈,这块用数组代替。这里就只构造一个链表)
C
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
struct ListNode
{
int m_nKey;
struct ListNode* m_pNext;
};
/* 随机产生n个元素的值,建立带表头结点的单链线性表L(尾插法) */
void CreateListTail(struct ListNode** L, int n)
{
struct ListNode* p;
struct ListNode* r;
int i;
srand((unsigned int)time(NULL)); /* 初始化随机数种子 */
*L = (struct ListNode*)malloc(sizeof(struct ListNode)); /* L为整个线性表 */
r = *L; /* r为指向尾部的结点 */
for (i = 0; i < n; i++)
{
p = (struct LilstNode*)malloc(sizeof(struct ListNode)); /* 生成新结点 */
if (NULL == (*L))
{
perror("开辟子节点空间失败");
}
p->m_nKey = rand() % 10; /* 随机生成100以内的数字 */
r->m_pNext = p; /* 将表尾终端结点的指针指向新结点 */
r = p; /* 将当前的新结点定义为表尾终端结点 */
}
r->m_pNext = NULL; /* 表示当前链表结束 */
}
/* 初始条件:链式线性表L已存在 */
/* 操作结果:依次对L的每个数据元素输出 */
void ListTraverse(struct ListNode* L)
{
struct ListNode* p = L->m_pNext;
while (p != NULL)
{
printf("%d ", p->m_nKey);
p = p->m_pNext;
}
printf("\n");
}
void PrintListReversing(struct ListNode* L)
{
int* n = (int*)malloc(10 * sizeof(int));
int size = 0; //实际元素个数
int length = 10; //数组长度
struct ListNode* p = L->m_pNext;
while (p != NULL)
{
if (size + 1 == length)//扩容
{
length += 10;
int* tmp = (int*)realloc(n, length * sizeof(int));
if (NULL == tmp)
{
perror("扩充失败!");
}
n = tmp;
tmp = NULL;
}
n[size++] = p->m_nKey;
p = p->m_pNext;
}
for (int i = size - 1; i >= 0; i--)
{
printf("%d ", n[i]);
}
}
int main()
{
struct ListNode* L;
CreateListTail(&L, 10);
printf("从前到后打印\n");
ListTraverse(L);
printf("从尾到头打印\n");
PrintListReversing(L);
return 0;
}
C++
#include <string>
#include <iostream>
#include <stack>
using namespace std;
class Node
{
public:
int data;
Node* next;
};
class LinkList
{
public:
LinkList();
~LinkList();
int CreateLinkList(int size);
int BYELinkList();
int TravalLinkList();
Node* head;
int size;
};
LinkList::LinkList()
{
head = new Node;
head->data = 0;
head->next = NULL;
size = 0;
}
LinkList::~LinkList()
{
delete head;
}
int LinkList::CreateLinkList(int n)//创建链表
{
if (n < 0) {
printf("error\n");
return -1;
}
Node* ptemp = NULL;
Node* pnew = NULL;
this->size = n;
ptemp = this->head;
for (int i = 0; i < n; i++)
{
pnew = new Node;
pnew->next = NULL;
cout << "输入第" << i + 1 << "个节点值" << endl;
cin >> pnew->data;
ptemp->next = pnew;
ptemp = pnew;
}
cout << "创建完成" << endl;
return 0;
}
int LinkList::BYELinkList()//销毁链表
{
Node* ptemp = NULL;
if (this->head == NULL) {
cout << "链表原本就为空" << endl;
return -1;
}
while (this->head)
{
ptemp = head->next;
delete head;
head = ptemp;
}
cout << "销毁链表完成" << endl;
return 0;
}
int LinkList::TravalLinkList()//输出链表
{
Node* ptemp = this->head->next;
if (this->head == NULL) {
cout << "链表为空" << endl;
return -1;
}
while (ptemp)
{
cout << ptemp->data << "->";
ptemp = ptemp->next;
}
cout << "NULL" << endl;
return 0;
}
void PrintListReversing(Node* list)//从尾到头打印
{
stack<int> nodes;
Node* ptemp = list->next;
while (ptemp != NULL)
{
nodes.push(ptemp->data);
ptemp = ptemp->next;
}
int temp = 0;
cout << "从尾到头打印链表" << endl;
while (nodes.empty() == false)//不为空
{
temp = nodes.top();
cout << temp << " ";
nodes.pop();
}
cout << endl;
}
int main(void)
{
LinkList list;
LinkList* plist = &list;
plist->CreateLinkList(5);
plist->TravalLinkList();
PrintListReversing(plist->head);
plist->BYELinkList();
system("pause");
return 0;
}
递归法
递归的本质就是栈结构,所以很自然的想到了用递归实现,我们访问到一个节点的时候,先递归输出后面的节点,在输出自身节点。
但是递归会有一个问题,当链表非常长的时候,就会导致函数调用的层级很深,从而导致函数调用栈溢出。显眼用栈基于循环实现的代码的鲁棒性要好一些。
C++
#include <string>
#include <iostream>
#include <stack>
using namespace std;
class Node
{
public:
int data;
Node* next;
};
class LinkList
{
public:
LinkList();
~LinkList();
int CreateLinkList(int size);
int BYELinkList();
int TravalLinkList();
Node* head;
int size;
};
LinkList::LinkList()
{
head = new Node;
head->data = 0;
head->next = NULL;
size = 0;
}
LinkList::~LinkList()
{
delete head;
}
int LinkList::CreateLinkList(int n)//创建链表
{
if (n < 0) {
printf("error\n");
return -1;
}
Node* ptemp = NULL;
Node* pnew = NULL;
this->size = n;
ptemp = this->head;
for (int i = 0; i < n; i++)
{
pnew = new Node;
pnew->next = NULL;
cout << "输入第" << i + 1 << "个节点值" << endl;
cin >> pnew->data;
ptemp->next = pnew;
ptemp = pnew;
}
cout << "创建完成" << endl;
return 0;
}
int LinkList::BYELinkList()//销毁链表
{
Node* ptemp = NULL;
if (this->head == NULL) {
cout << "链表原本就为空" << endl;
return -1;
}
while (this->head)
{
ptemp = head->next;
delete head;
head = ptemp;
}
cout << "销毁链表完成" << endl;
return 0;
}
int LinkList::TravalLinkList()//输出链表
{
Node* ptemp = this->head->next;
if (this->head == NULL) {
cout << "链表为空" << endl;
return -1;
}
while (ptemp)
{
cout << ptemp->data << "->";
ptemp = ptemp->next;
}
cout << "NULL" << endl;
return 0;
}
void PrintListReversing(Node* list)//从尾到头打印
{
if (NULL != list)
{
if (list->next != NULL)
{
PrintListReversing(list->next);
}
cout << list->data << " ";
}
}
int main(void)
{
LinkList list;
LinkList* plist = &list;
plist->CreateLinkList(5);
plist->TravalLinkList();
PrintListReversing(plist->head->next);
plist->BYELinkList();
system("pause");
return 0;
}
本章完!