线性表完结

This commit is contained in:
Ruvikm
2021-01-14 20:01:42 +08:00
parent 50e5ad1e4f
commit 7c4b9a10c6
10 changed files with 1260 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.16
//两个整数序列A = a1,a2,a3…, an和B = b1, b2, b3, …, bn已经存入两个单链表中, 设计
//个算法, 判断序列B是否是序列A的连续子序列
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
list = list->next;
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.16
bool Subsequences(LinkList& A, LinkList& B) {
LinkList pa = A->next, pb = B->next, pre = pa;
while (pa && pb) {
if (pa->data == pb->data) {
pa = pa->next;
pb = pb->next;
}
else {
pre = pre->next;
pa = pre;
pb = B->next;
}
}
if (!pb)
return true;
else
return false;
}
int main()
{
cout << "输入数据:" << endl;
vector<int> data1{ 1,3,5,7,9,11 };
vector<int> data2{ 3,5,7,9 };
LinkList A;
InitList(A);
LinkList B;
InitList(B);
A = CreatList(data1);
B = CreatList(data2);
PrintList(A);
PrintList(B);
cout << "测试结果:" << endl;
if (Subsequences(A, B)) {
cout << "序列B是序列A的连续子序列" << endl;
}
else {
cout << "序列B不是序列A的连续子序列" << endl;
}
return 0;
}

View File

@@ -0,0 +1,119 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.17
//设计一个算法用于判断带头结点的循环双链表是否对称
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的循环双链表
typedef struct LNode {
ElemType data;
struct LNode* next, * prior;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = L;
L->prior = L;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == L);
}
//判断结点P是否为表尾结点
bool IsTail(LinkList L, LNode* p) {
return (p->next == L);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
s->prior = p;
p->next = s;
p = s;
}
p->next = head;
head->prior = p;
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
LinkList plist = list->next;
while (plist->next != list->next) {
printf("%d ", plist->data);
plist = plist->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.17
bool Palindrome(LinkList& A) {
LinkList P = A->next;
LinkList Q = A->prior;
for (; P->data == Q->data && (P->prior != Q && P != Q ); P = P->next, Q = Q->prior);
if (P->prior == Q || P == Q)
return true;
return false;
}
int main()
{
cout << "输入数据:" << endl;
vector<int> data1{ 1,3,7,7,3,1 }; // 偶数
/*vector<int> data1{ 1,3,7,9,7,3,1 };*/ //奇数
LinkList A;
InitList(A);
A = CreatList(data1);
PrintList(A);
cout << "测试结果:" << endl;
if (Palindrome(A)) {
cout << "序列A对称" << endl;
}
else {
cout << "序列A不对称" << endl;
}
return 0;
}

View File

@@ -0,0 +1,118 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.18
//有两个循环单链表, 链表头指针分别为h1和h2, 编写一个函数将链表h2链接到链表
//h1之后, 要求链接后的链表仍保持循环链表形式
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的循环单链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = L;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == L);
}
//判断结点P是否为表尾结点
bool IsTail(LinkList L, LNode* p) {
return (p->next == L);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
p->next = head;
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
LinkList plist = list->next;
while (plist->next != list->next) {
printf("%d ", plist->data);
plist = plist->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.18
LinkList Merger(LinkList &A,LinkList &B) {
LinkList pa = A->next;
LinkList pb = B->next;
for (; pa->next != A; pa = pa->next);
for (; pb->next != B; pb = pb->next);
pa->next = B->next;
pb->next = A;
return A;
}
int main()
{
cout << "输入数据:" << endl;
vector<int> data1{ 1,3,5,9,7,1 };
vector<int> data2{ 2,4,6,8,4,2 };
LinkList A;
InitList(A);
A = CreatList(data1);
PrintList(A);
LinkList B;
InitList(B);
B = CreatList(data2);
PrintList(B);
cout << "测试结果:" << endl;
A = Merger(A, B);
PrintList(A);
return 0;
}

View File

@@ -0,0 +1,133 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.19
//设有一个带头结点的循环单链表,其结点值均为正整数。设计一个算法,反复找出单链
//表中结点值最小的结点并输出,然后将该结点从中删除, 直到单链表空为止,再删除表
//头结点。
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的循环单链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = L;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == L);
}
//判断结点P是否为表尾结点
bool IsTail(LinkList L, LNode* p) {
return (p->next == L);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
p->next = head;
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
LinkList plist = list->next;
while (plist->next != list->next) {
printf("%d ", plist->data);
plist = plist->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.19
void DelMinPrint(LinkList& A) {
LinkList p = A->next;
LinkList pre = A;
LNode* minp = p;
LNode* minpre = A;
while (A->next != A)
{
p = A->next;
pre = A;
minp = p;
minpre = pre;
while (p != A) {
if (p->data < minp->data) {
minp = p;
minpre = pre;
}
else {
pre = p;
p = p->next;
}
}
minpre->next = minp->next;
cout << minp->data<<" ";
delete minp;
}
cout << endl;
}
int main()
{
cout << "输入数据:" << endl;
vector<int> data1{ 1,3,5,9,7,2 };
LinkList A;
InitList(A);
A = CreatList(data1);
PrintList(A);
cout << "测试结果:" << endl;
DelMinPrint(A);
PrintList(A);
return 0;
}

View File

@@ -0,0 +1,129 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.20
//设头指针为L的带有表头结点的非循环双向链表, 其每个结点中除有pred(前驱
//指针)、data(数据)和next(后继指针)域外, 还有一个访问频度域freq。在
//链表被启用前, 其值均初始化为零。每当在链表中进行一次 Locate(L, x)运算时
//令元素值为ⅹ的结点中freq域的值增1, 并使此链表中结点保持按访问频度非增
//(递减)的顺序排列, 同时最近访问的结点排在频度相同的结点前面, 以便使频繁
//访问的结点总是靠近表头。试编写符合上述要求的 Locate(L, x)运算的算法, 该
//运算为函数过程, 返回找到结点的地址, 类型为指针型
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的双链表
typedef struct LNode {
ElemType data;
struct LNode* next, * prior;
int freq = 0;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
L->prior = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
s->prior = p;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
LinkList plist = list->next;
while (plist != NULL) {
printf("%d ", plist->data);
plist = plist->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.20
LNode* Locate(LinkList L, int x) {
LinkList p = L->next, pre = L;
for (; p && p->data != x; p = p->next);
if (!p) {
cout << "x is not exist!" << endl;
return NULL;
}
else {
(p->freq)++;
p->prior->next = p->next;
p->next->prior = p->prior;
pre = p->prior;
for (; pre != L && pre->freq <= p->freq; pre = pre->prior);
p->next = pre->next;
pre->next->prior = p;
p->prior = pre;
pre->next = p;
}
return p;
}
int main()
{
cout << "输入数据:" << endl;
vector<int> data1{ 1,3,4,7,2,1 };
LinkList A;
InitList(A);
A = CreatList(data1);
PrintList(A);
cout << "测试结果:" << endl;
Locate(A, 3);
Locate(A, 99);
Locate(A, 4);
Locate(A, 4);
Locate(A, 2);
Locate(A, 7);
PrintList(A);
return 0;
}

View File

@@ -0,0 +1,140 @@
#include <iostream>
#include <vector>
using namespace std;
//P42.21
//已知一个带有表头结点的单链表,结点结构为
// data link
//假设该链表只给出了头指针1ist。在不改变链表的前提下, 请设计一个尽可能高效的
//算法, 查找链表中倒数第k个位置上的结点(k为正整数)。若查找成功, 算法输出该结
//点的data域的值, 并返回1; 否则, 只返回0。
//1)描述算法的基本设计思想
//2)描述算法的详细实现步骤
//3)根据设计思想和实现步骤, 采用程序设计语言描述算法(使用C、C++或Java语
//实现), 关键之处请给出简要注释
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->data = NULL;
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
list = list->next;
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.21
//自己版本
int PenultiMateK(LinkList L, int k) {
int len = Getlen(L);
int pin = len - k ;
int count = 1;
LinkList p = L->next;
for (; p && count != pin; p = p->next, count++);
if (p) {
cout << p->data;
return 1;
}
else {
cout << "The element in the penultimate k position does not exist" << endl;
return 0;
}
}
//书上版本
int Search_K(LinkList L, int k) {
int count = 0;
LinkList p = L->next, pk = p;
while (p) {
if (count < k)
count++;
else
pk = pk->next;
p = p->next;
}
if (count < k) {
cout << "The element in the penultimate k position does not exist" << endl;
return 0;
}
else {
cout << pk->data;
return 1;
}
}
int main()
{
vector<int> data{ 1,3,5,7,9,11,13,15 };
LinkList head;
InitList(head);
head = CreatList(data);
PrintList(head);
//PenultiMateK(head, 3);
Search_K(head, 8);
return 0;
}

View File

@@ -0,0 +1,131 @@
#include <iostream>
#include <vector>
using namespace std;
//P43.22
//假定采用带头结点的单链表保存单词,当两个单词有相同的后缀时,
//可共享相同的后缀存储空间,例如,“loading”和 “being”的存储映像如下图所示。
//设str1和str2分别指向两个单词所在单链表的头结点, 链表结点结构为data,next,
//请设计一个时间上尽可能高效的算法, 找出由Str1和str2所指向两个链表共同后缀
//的起始位置(如图中字符i所在结点的位置p)。要求
//1)给出算法的基本设计思想
//2)根据设计思想, 采用C或C++或Java语言描述算法, 关键之处给出注释
//3)说明你所设计算法的时间复杂度
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->data = NULL;
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P42.22
LinkList FindCom(LinkList A,LinkList B) {
int len1 = Getlen(A), len2 = Getlen(B), Diff = abs(len1 - len2);
LinkList longlist, shortlist;
if (len1 > len2) {
longlist = A->next;
shortlist = B->next;
}
else {
longlist = B->next;
shortlist = A->next;
}
while (Diff--)
longlist = longlist->next;
while (longlist) {
if (longlist == shortlist)
return longlist;
longlist = longlist->next;
shortlist = shortlist->next;
}
}
int main()
{
vector<int> data1{ 3,5,6,8,1,4,9,77 };
vector<int> data2{ 2,5,7,88,31 };
LinkList head1;
LinkList head2;
InitList(head1);
InitList(head2);
head1 = CreatList(data1);
head2 = CreatList(data2);
LinkList com = head1->next;
LinkList P = head2->next;
for (; com != NULL && com->data != 8; com = com->next);
for (; P->next != NULL; P = P->next);
P->next = com;
PrintList(head1->next);
PrintList(head2->next);
LinkList C = FindCom(head1, head2);
PrintList(C);
return 0;
}

View File

@@ -0,0 +1,121 @@
#include <iostream>
#include <vector>
using namespace std;
//P43.23
//用单链表保存m个整数, 结点的结构为[data][1ink], 且 |data| ≤ n
//(n为正整数)。现要求设计一个时间复杂度尽可能高效的算法, 对于链表中data的绝对值
//相等的结点, 仅保留第一次出现的结点而删除其余绝对值相等的结点。
//要求
//1)给出算法的基本设计思想
//2)使用C或C + 语言, 给出单链表结点的数据类型定义
//3)根据设计思想, 采用C或C + 语言描述算法, 关键之处给出注释
//4)说明你所设计算法的时间复杂度和空间复杂度
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#define N 30
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->data = NULL;
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
list = list->next;
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P43.23
void de_duplication(LinkList L) {
vector<int> box(N + 1, 0);
LinkList p = L->next, pre = L;
while(p) {
if (!box[abs(p->data)]) {
box[abs(p->data)] = 1;
pre = p;
p = p->next;
}
else {
LNode* r = p->next;
pre->next = p->next;
delete p;
p = r;
}
}
box.clear();
}
int main()
{
vector<int> data{ 21,-11,-15,-7,15,11,13,15 };
LinkList head;
InitList(head);
head = CreatList(data);
PrintList(head);
de_duplication(head);
PrintList(head);
return 0;
}

View File

@@ -0,0 +1,113 @@
#include <iostream>
#include <vector>
using namespace std;
//P44,24
//设计一个算法完成以下功能:判断一个链表是否有环, 如果有, 找出环的入口点并返回,
//否则返回NULL
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->data = NULL;
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
//list = list->next;
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P43.24
LNode* FindCycle(LinkList L) {
LinkList fast = L, slow = L;
while (slow != NULL && fast->next != NULL) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast)
break;
}
if (slow == NULL || (fast->next == NULL))
return NULL;
LinkList p = L, q = slow;
for (; p != q; p = p->next, q = q->next);
return q;
}
int main()
{
vector<int> data{ 1,3,5,7,9,11,13,15 };
LinkList head;
InitList(head);
head = CreatList(data);
LinkList p = head->next, q = p;
for (; p->next; p = p->next);
for (; q->next && q->data != 9; q = q->next);
p->next = q;
//PrintList(head->next);
LinkList cycle = FindCycle(head);
PrintList(cycle);
return 0;
}

View File

@@ -0,0 +1,132 @@
#include <iostream>
#include <vector>
using namespace std;
//P44.25
//设线性表L = (a1,a2, a3,…, an-2,an-1,an)采用带头结点的单链表保存
//请设计一个空间复杂度为O(1)且时间上尽可能高效的算法, 重新排列 L中的各结点, 得
//到线性表L = (a1, an,a2,an-1, a3, an-2…)。要求
//1)给出算法的基本设计思想
//2)根据设计思想, 采用C或C艹语言描述算法, 关键之处给出注释
//3)说明你所设计的算法的时间复杂度
#define ElemType int
#define _for(i,a,b) for(int i=(a);i<(b);i++)
#define INF 0x3f3f3f3f
#pragma region 建立带头结点的链表
typedef struct LNode {
ElemType data;
struct LNode* next;
}LNode, * LinkList;
//初始化链表
bool InitList(LinkList& L) {
//分配一个头结点
L = (LNode*)malloc(sizeof(LNode));
//内存不足,分配失败
if (L == NULL) {
return false;
}
//头结点之后暂时还没有节点
L->next = NULL;
return true;
}
//判断是否为空
bool IsEmpty(LinkList L) {
return ((L->next) == NULL);
}
//使用尾插法建表
LinkList CreatList(vector<int> data) {
if (data.size() < 1) {
return NULL;
}
//头结点
LNode* head = (LinkList)malloc(sizeof(LNode));
head->data = NULL;
head->next = NULL;
LinkList p = head;
_for(i, 0, data.size()) {
LNode* s = (LinkList)malloc(sizeof(LNode));
s->data = data[i];
s->next = NULL;
p->next = s;
p = s;
}
return head;
}
//输出链表
void PrintList(LinkList list) {
if (IsEmpty(list)) {
cout << "the list is null" << endl;
return;
}
list = list->next;
while (list != NULL) {
printf("%d ", list->data);
list = list->next;
}
printf("\n");
}
int Getlen(LinkList L) {
int len = 0;
while (L != NULL) {
L = L->next;
len++;
}
return len;
}
#pragma endregion
//P44.25
void Custom_sort(LinkList& L) {
LinkList p, q, r, s;
p = q = L;
while (q->next != NULL) {
p = p->next;
q = q->next;
if (q->next != NULL) {
q = q->next;
}
}
q = p->next;
p->next = NULL;
while (q != NULL) {
r = q->next;
q->next = p->next;
p->next = q;
q = r;
}
s = L->next;
q = p->next;
p->next = NULL;
while (q != NULL) {
r = q->next;
q->next = s->next;
s->next = q;
s = q->next;
q = r;
}
}
int main()
{
vector<int> data{ 1,3,5,7,15,13,11,9 };
LinkList head;
InitList(head);
head = CreatList(data);
PrintList(head);
Custom_sort(head);
PrintList(head);
return 0;
}