有一个带头结点的单链表L,设计一个算法利用一个链栈将其所有结点逆置。
思路
首先,定义一系列的常量和类型,包括 Status
,ElemType
,ListNode
,LinkedList
,StackNode
,和 LinkedStack
。然后,定义一个数组 a[N]
,用于存储输入的元素。
在 main
函数中,首先从标准输入中读取元素的数量 n
,然后读取 n
个元素,存储在数组 a
中。接着,初始化一个单链表 L
,并将数组 a
中的元素按顺序插入到链表 L
中。然后,打印出链表 L
中的所有元素。
接下来,初始化一个链栈 S
,并将链表 L
中的所有元素依次出链表并入栈到 S
中。然后,清空链表 L
。
然后,将栈 S
中的所有元素依次出栈并插入到链表 L
中。这样就实现了链表的逆置。最后,打印出逆置后的链表 L
中的所有元素。
在时间复杂度方面,主要的计算步骤是链表的插入、读取和清空,以及栈的入栈和出栈。这些操作的时间复杂度都是 O ( 1 ) O(1) O(1)。因此,整个程序的时间复杂度是 O ( n ) O(n) O(n),其中 n n n 是链表的长度。
在空间复杂度方面,主要的存储空间是用于存储链表和栈的空间。这两个空间的大小都与链表的长度 n n n 成正比,因此,整个程序的空间复杂度也是 O ( n ) O(n) O(n)。
代码
#include <algorithm>
#include <iostream>
#define AUTHOR "HEX9CF"
using namespace std;
using Status = int;
using ElemType = int;
const int N = 1e6 + 7;
const int TRUE = 1;
const int FALSE = 0;
const int OK = 1;
const int ERROR = 0;
const int INFEASIBLE = -1;
// const int OVERFLOW = -2;
int n;
ElemType a[N];
struct ListNode {
ElemType data;
ListNode *next;
};
using LinkedList = ListNode *;
Status initList(LinkedList &first) {
first = (ListNode *)malloc(sizeof(ListNode));
if (!first) {
return ERROR;
}
first->next = NULL;
return OK;
}
Status listInsert(LinkedList &L, int pos, ElemType e) {
ListNode *p = L;
for (int i = 0; p && i < pos; i++) {
p = p->next;
}
if (!p) {
return ERROR;
}
ListNode *newNode = (ListNode *)malloc(sizeof(ListNode));
if (!newNode) {
return ERROR;
}
newNode->data = e;
newNode->next = p->next;
p->next = newNode;
return OK;
}
ElemType getElem(LinkedList L, int pos) {
ListNode *p = L->next;
for (int i = 0; p && i < pos; i++) {
p = p->next;
}
if (!p) {
return NULL;
}
return p->data;
}
Status listClear(LinkedList &first) {
ListNode *p = first->next;
while (p) {
ListNode *q = p;
p = p->next;
free(q);
q = NULL;
}
return OK;
}
struct StackNode {
ElemType data;
StackNode *next;
};
struct LinkedStack {
StackNode *top;
};
Status initStack(LinkedStack &S) {
S.top = NULL;
return OK;
}
Status stackPush(LinkedStack &S, ElemType e) {
StackNode *newNode = (StackNode *)malloc(sizeof(StackNode));
if (!newNode) {
return ERROR;
}
newNode->data = e;
newNode->next = S.top;
S.top = newNode;
return OK;
}
bool stackEmpty(LinkedStack S) { return (S.top == NULL); }
ElemType stackTop(LinkedStack S) {
if (stackEmpty(S)) {
return NULL;
}
return S.top->data;
}
Status stackPop(LinkedStack &S) {
if (stackEmpty(S)) {
return ERROR;
}
StackNode *p = S.top;
S.top = p->next;
free(p);
p = NULL;
return OK;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) {
cin >> a[i];
}
LinkedList L;
initList(L);
for (int i = 0; i < n; i++) {
listInsert(L, i, a[i]);
}
for (int i = 0; i < n; i++) {
cout << getElem(L, i) << " ";
}
cout << "\n";
LinkedStack S;
initStack(S);
for (int i = 0; i < n; i++) {
ElemType e = getElem(L, i);
stackPush(S, e);
}
listClear(L);
for (int i = 0; i < n; i++) {
ElemType e = stackTop(S);
stackPop(S);
listInsert(L, i, e);
}
for (int i = 0; i < n; i++) {
cout << getElem(L, i) << " ";
}
cout << "\n";
return 0;
}