Mobile wallpaper 1Mobile wallpaper 2Mobile wallpaper 3Mobile wallpaper 4Mobile wallpaper 5
1156 字
6 分钟
【数据结构】一般线性表
2025-09-26
统计加载中...

代码会在结束后更新,题都很简单,恶心的一点是不给数据范围让用户自己试

函数题#

带头结点的链式表操作集#

List MakeEmpty() {
return malloc(sizeof(struct LNode));
}
Position Find( List L, ElementType X ) {
while (L) {
if (L->Data == X) return L;
L = L->Next;
}
return ERROR;
}
bool Insert( List L, ElementType X, Position P ) {
while (L && L->Next != P) {
L = L->Next;
}
if (!L) {
printf("Wrong Position for Insertion\n");
return false;
}
List t = malloc(sizeof(struct LNode));
t->Data = X;
t->Next = L->Next, L->Next = t;
return true;
}
bool Delete( List L, Position P ) {
if (!P) {
printf("Wrong Position for Deletion\n");
return false;
}
while (L && L->Next != P) {
L = L->Next;
}
if (!L || !L->Next) {
printf("Wrong Position for Deletion\n");
return false;
}
L->Next = P->Next;
free(P);
return true;
}

求链表的倒数第m个元素#

ElementType Find( List L, int m ) {
int len = 0;
for (List t = L; t; t = t->Next) len++;
m = len - m;
while (L && m--) L = L->Next;
return L ? L->Data : ERROR;
}

单链表分段逆转#

一段一段做,段内反转,同时需要记录下一个点和这段最左边的点的地址,段间连起来,第 4 个点段错误是因为没有特判 n < k 爆掉了,别问我怎么知道的。

void K_Reverse( List L, int K ) {
int len = 0;
for (List p = L; p; p = p->Next) len++;
len--;
if (len < K) return;
len = len / K * K;
List h = L, cur, pre, tmp;
L = L->Next;
for (int i = 0; i < len; i += K) {
cur = L, pre = L, tmp = NULL;
L = L->Next;
for (int j = 1; j < K; ++j) {
tmp = L->Next;
L->Next = pre;
pre = L;
L = tmp;
}
h->Next = pre;
h = cur;
}
h->Next = tmp;
}

共享后缀的链表#

先往后移动长的链表的头指针,对齐之后同时右移,直到重合,类似暴力的 lca 的做法。

PtrToNode Suffix( List L1, List L2 ) {
int l1 = 0, l2 = 0;
for (List p = L1->Next; p; p = p->Next) l1++;
for (List q = L2->Next; q; q = q->Next) l2++;
if (l1 > l2) for (int i = 0; i < l1 - l2; ++i) L1 = L1->Next;
else for (int i = 0; i < l2 - l1; ++i) L2 = L2->Next;
while (L1 && L1 != L2) L1 = L1->Next, L2 = L2->Next;
return L1;
}

编程题#

两个有序链表序列的合并#

参考归并排序的合并

#include <iostream>
#include <list>
using namespace std;
int main() {
list<int> a, b, c; // STL!爽!
int t;
while (scanf("%d", &t), t != -1) a.emplace_back(t);
while (scanf("%d", &t), t != -1) b.emplace_back(t);
auto h1 = a.begin(), h2 = b.begin();
while (h1 != a.end() && h2 != b.end()) {
if (*h1 <= *h2) c.emplace_back(*h1++);
else c.emplace_back(*h2++);
}
while (h1 != a.end()) c.emplace_back(*h1++);
while (h2 != b.end()) c.emplace_back(*h2++);
if (c.empty()) printf("NULL");
for (auto h = c.begin(); h != c.end(); h++) {
if (h == c.begin()) printf("%d", *h);
else printf(" %d", *h);
}
return 0;
}

一元多项式的乘法与加法运算#

其实就是一个高精乘法和高精加法,而且不用进位。个人感觉他的本意是想考链表,但是数据给太小了,直接开 2000 的数组就能跑过去。如果 p 给个 106 以上那就得老老实实用链表了。

#include <iostream>
using namespace std;
const int N = 1010;
int a[N], b[N], c[N * 2];
int main() {
int n, m;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
int t, p;
scanf("%d%d", &t, &p);
a[p] = t;
}
scanf("%d", &m);
for (int i = 1; i <= m; ++i) {
int t, p;
scanf("%d%d", &t, &p);
b[p] = t;
}
for (int i = 0; i <= 1000; ++i) {
for (int j = 0; j <= 1000; ++j) {
c[i + j] += a[i] * b[j];
}
}
bool print = false;
for (int i = 2000; i >= 0; --i) {
if (c[i]) {
if (!print) print = true, printf("%d %d", c[i], i);
else printf(" %d %d", c[i], i);
}
}
if (!print) printf("0 0\n");
else printf("\n");
for (int i = 0; i <= 1000; ++i) a[i] += b[i];
print = false;
for (int i = 1000; i >= 0; --i) {
if (a[i]) {
if (!print) print = true, printf("%d %d", a[i], i);
else printf(" %d %d", a[i], i);
}
}
if (!print) printf("0 0\n");
else printf("\n");
return 0;
}

多项式 A 除以 B#

这道其实是高精除法,本意应该也是想考链表,但是实测数组开 104 能过,p 给个 105 以上差不多就能卡掉数组了。

#include <iostream>
#include <cmath>
using namespace std;
const int N = 10010;
const double eps = 0.05;
double a[N], b[N], c[N];
void print(double a[]) {
int t = 0;
for (int i = 0; i <= 10000; ++i) {
if (fabs(a[i]) >= eps) t++;
}
if (!t) printf("0 0 0.0\n");
else {
printf("%d", t);
for (int i = 10000; i >= 0; --i) {
if (fabs(a[i]) >= eps) printf(" %d %.1lf", i, a[i]);
}
printf("\n");
}
}
int main() {
int n, m, l1 = 0, l2 = 0;
scanf("%d", &n);
for (int i = 1; i <= n; ++i) {
int t, p;
scanf("%d%d", &p, &t);
l1 = max(l1, p);
a[p] = t;
}
scanf("%d", &m);
for (int i = 1; i <= m; ++i) {
int t, p;
scanf("%d%d", &p, &t);
l2 = max(l2, p);
b[p] = t;
}
for (int i = l1 - l2; i >= 0; --i) {
if (a[i + l2]) {
c[i] = a[i + l2] / b[l2];
for (int j = 0; j <= l2; ++j) {
a[i + j] -= c[i] * b[j];
}
}
}
print(c);
print(a);
return 0;
}
【数据结构】一般线性表
https://starlab.top/posts/ds-contest1/
作者
Star
发布于
2025-09-26
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时