diff --git a/线性表/链式实现大题/P42.16.cpp b/线性表/链式实现大题/P42.16.cpp new file mode 100644 index 0000000..b58cc19 --- /dev/null +++ b/线性表/链式实现大题/P42.16.cpp @@ -0,0 +1,124 @@ +#include +#include +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 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 data1{ 1,3,5,7,9,11 }; + vector 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; +} diff --git a/线性表/链式实现大题/P42.17.cpp b/线性表/链式实现大题/P42.17.cpp new file mode 100644 index 0000000..a365f37 --- /dev/null +++ b/线性表/链式实现大题/P42.17.cpp @@ -0,0 +1,119 @@ +#include +#include +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 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 data1{ 1,3,7,7,3,1 }; // 偶数 + /*vector 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; +} diff --git a/线性表/链式实现大题/P42.18.cpp b/线性表/链式实现大题/P42.18.cpp new file mode 100644 index 0000000..5586be9 --- /dev/null +++ b/线性表/链式实现大题/P42.18.cpp @@ -0,0 +1,118 @@ +#include +#include +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 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 data1{ 1,3,5,9,7,1 }; + vector 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; +} diff --git a/线性表/链式实现大题/P42.19.cpp b/线性表/链式实现大题/P42.19.cpp new file mode 100644 index 0000000..923773e --- /dev/null +++ b/线性表/链式实现大题/P42.19.cpp @@ -0,0 +1,133 @@ +#include +#include +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 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 data1{ 1,3,5,9,7,2 }; + LinkList A; + InitList(A); + A = CreatList(data1); + PrintList(A); + cout << "测试结果:" << endl; + DelMinPrint(A); + PrintList(A); + return 0; +} diff --git a/线性表/链式实现大题/P42.20.cpp b/线性表/链式实现大题/P42.20.cpp new file mode 100644 index 0000000..852ee70 --- /dev/null +++ b/线性表/链式实现大题/P42.20.cpp @@ -0,0 +1,129 @@ +#include +#include +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 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 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; +} diff --git a/线性表/链式实现大题/P42.21.cpp b/线性表/链式实现大题/P42.21.cpp new file mode 100644 index 0000000..360543b --- /dev/null +++ b/线性表/链式实现大题/P42.21.cpp @@ -0,0 +1,140 @@ +#include +#include +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 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 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; +} diff --git a/线性表/链式实现大题/P43.22.cpp b/线性表/链式实现大题/P43.22.cpp new file mode 100644 index 0000000..80ad67a --- /dev/null +++ b/线性表/链式实现大题/P43.22.cpp @@ -0,0 +1,131 @@ +#include +#include +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 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 data1{ 3,5,6,8,1,4,9,77 }; + vector 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; +} diff --git a/线性表/链式实现大题/P43.23.cpp b/线性表/链式实现大题/P43.23.cpp new file mode 100644 index 0000000..4033909 --- /dev/null +++ b/线性表/链式实现大题/P43.23.cpp @@ -0,0 +1,121 @@ +#include +#include +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 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 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 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; +} diff --git a/线性表/链式实现大题/P44.24.cpp b/线性表/链式实现大题/P44.24.cpp new file mode 100644 index 0000000..46b0d1d --- /dev/null +++ b/线性表/链式实现大题/P44.24.cpp @@ -0,0 +1,113 @@ +#include +#include +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 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 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; +} diff --git a/线性表/链式实现大题/P44.25.cpp b/线性表/链式实现大题/P44.25.cpp new file mode 100644 index 0000000..511857f --- /dev/null +++ b/线性表/链式实现大题/P44.25.cpp @@ -0,0 +1,132 @@ +#include +#include +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 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 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; +}