diff --git a/LinkListOperation/LinkList.h b/LinkListOperation/LinkList.h new file mode 100644 index 0000000..7914d52 --- /dev/null +++ b/LinkListOperation/LinkList.h @@ -0,0 +1,253 @@ + +template +struct LNode //链表结点 +{ + DT data; //数据域,存储数据元素值 + LNode* next; //指针域,指向下一个结点 +}; + +//算法2.1 +template +bool PriorElem_e(LNode
* L, DT e, DT& pre_e) // 求值为e的元素前驱 +{ + int k; + k = LocateElem_e(L, e); // 1.获取e的位序k + if (k > 1) // 2.位序k大于1 + { + GetElem_i(L, k - 1, pre_e); // 第k-1个元素为e的前驱 + return true; + } + else // 3.元素e无前驱 + return false; // 返回false +} + +//【算法2.14】 创建空单链表 +template +bool InitList(LNode
*& L) +{ + L = new LNode
; // 1.创建头结点 + if (!L) exit(1); // 2.创建失败,退出 + L->next = NULL; // 3.创建成功 + return true; // 返回true +} + +//【算法2.15】 尾插法创建n的元素 +template +bool CreateList_1(LNode
*& L, int n) +{ + int i; + LNode
* p, * s; + p = L; //1.工作指针初始化,指向尾结点 + cout << "依次输入" << n << "个数据元素:" << endl; + for (i = 1; i <= n; i++) // 2.按元素位序正序创建各结点 + { + s = new LNode
; // 2.1 新建一个结点s + if (!s) // 2.2 创建失败,返回false + return false; + cin >> s->data; // 2.3 输入结点值 + s->next = p->next; // 2.4 s 链在表尾 + p->next = s; + p = s; // 2.5 工作指针指向 s + } + return true; // 3.创建成功,返回true +} + +//【算法2.16】 头插法创建n个元素 +template +bool CreateList_2(LNode
* (&L), int n) +{ + int i; + LNode
* s; + cout << "逆序输入" << n << "个数据元素:" << endl; + for (i = 1; i <= n; i++) // 1.按元素位序逆序创建各结点 + { + s = new LNode
; // 1.1 新建一个结点 s + if (!s) // 1.2 创建失败,返回false + return false; + cin >> s->data; // 1.3 输入结点值 + s->next = L->next; // 1.4 s 在头结点后 + L->next = s; + } + return true; // 1.创建成功,返回true +} + +//【算法2.17】 +template +void DestroyList(LNode
* (&L)) // 释放链表所占空间 +{ + LNode
* p; + while (L) // 1. 表非空,从头结点开始,依次释放结点 + { + p = L; // 1.1 处理表头结点 + L = L->next; // 1.2 头指针后移 + delete p; // 1.3 释放表头结点所占内存 + } + L = NULL; // 2.头指针指向空 +} + +//【算法2.18】 获取第i个元素 +template +bool GetElem_i(LNode
* L, int i, DT& e) +{ + LNode
* p; // 1.初始化 + p = L->next; // 1.1 设置工作指针,从首结点开始数结点 + int j = 1; // 1.2 计数器初始化 + while (p && j < i) // 2.定位到第i个元素结点 + { + p = p->next; j++; + } + if (!p || j > i) // 3 未找到,返回false + return false; + else // 4. 找到 + { + e = p->data; // 获取第i个元素值 + return true; // 返回true + } +} + +//【算法2.19】 查找值为e的元素位序 +template +int LocateElem_e(LNode
* L, DT e) +{ + + LNode
* p; // 1.初始化从首元开始查找 + p = L->next; // 1.1从首元开始查找 + int j = 1; // 1.2 计数器初值 + while (p && p->data != e) // 2.顺序查找 + { + p = p->next; // 2.1未找到指针后移 + j++; // 2.2 计数器增1 + } + if (p == NULL) // 3. 判断是否找到 + return 0; // 3.1末找到,返回0 + else + return j; // 3.2 找到,返回位序 +} + +//【算法2.20】 插入第i个元素 +template +bool InsertElem_i(LNode
*& L, int i, DT e) +{ + + int j = 0; + LNode
* p; // 1.初始化 + p = L; // 工作指针初始化 + while (p && j < i - 1) // 2. 定位到插入点前驱 + { + p = p->next; + j++; + } + if (!p || j > i - 1) // 3.判断定位是否成功: + return false; // 3.1 定位失败,不能插入 + else // 3.2 定位成功 + { + LNode
* s; + s = new LNode
; // 3.2.1建立新结点 + s->data = e; // 3.2.2新结点赋值 + s->next = p->next; // 3.2.3结点S链接到p结点之后 + p->next = s; + return true; // 3.2.4 插入成功,返回true + } + +} + +//【算法2.21】 删除第i个元素 +template +bool DeleElem_i(LNode
* (&L), int i) +{ + + LNode
* p, * q; //1.初始化:设置工作指针 + p = L; //查找从头结点开始 + int j = 0; //计数器初始化 + while (p->next && j < i - 1) //2.p定位到删除点的前驱 + { + p = p->next; + j++; + } + if (!p->next || j > i - 1) //3.删除位置不合理,不能删除 + return false; //返回false + else //4.删除操作 + { + q = p->next; //4.1暂存删除结点位置 + p->next = q->next; //4.2从链表中摘除删除结点 + delete q; + return true; //4.3删除成功,返回true + } +} + + +//【算法2.22】 修改第i个元素值 +template +bool PutElem_i(LNode
* (&L), int i, DT e) +{ + LNode
* p; // 1.初始化:设置工作指针 + p = L->next; // 从首结点开始,数结点 + int j = 1; // 计数器初始化 + while (p && j < i) // 2.查找第i个元素结点 + { + p = p->next; j++; + } + if (!p || j > i) // 3.元素不存在,返回false + return false; + else // 4.定位成功 + { + p->data = e; // 修改元素值 + return true; // 返回true + } +} + +// 释放链表所占空间 +template +void ClearList(LNode
* (&L)) +{ + + LNode
* p; + while (L->next) // 从首元结点开始,依次释放结点 + { + p = L->next; + L->next = p->next; + delete p; + } + cout << endl << "表已清空!" << endl; +} + + +//【算法2.23】 测表长 +template +int ListLength(LNode
* L) +{ // 1.初始化 + int len = 0; // 1.1 结点计数器赋初值0 + LNode
* p; // 1.2设置工作指针 + p = L; // 指向头结点 + while (p->next) // 2.数结点个数。有后继结点, + { + len++; p = p->next; // 结点数增1,指针后移 + } + return len; // 3.返回表长 +} + +// +template +bool ListEmpty(LNode
* L) //测表空 +{ + if (L->next == NULL) + return true; //空表,返回1 + else + return false; //不空,返回0 +} + + +//【算法2.24】 遍历表 +template +void DispList(LNode
* L) // 显示表内容 +{ + LNode
* p; // 1. 设置工作指针 + p = L; // 从首元结点开始遍历 + while (p->next) // 2.依次输出各结点值 + { + p = p->next; cout << p->data << "\t"; + + + } + cout << endl; +} diff --git a/LinkListOperation/LinkListOperation.sln b/LinkListOperation/LinkListOperation.sln new file mode 100644 index 0000000..33b9616 --- /dev/null +++ b/LinkListOperation/LinkListOperation.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.9.34701.34 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LinkListOperation", "LinkListOperation.vcxproj", "{BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Debug|x64.ActiveCfg = Debug|x64 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Debug|x64.Build.0 = Debug|x64 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Debug|x86.ActiveCfg = Debug|Win32 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Debug|x86.Build.0 = Debug|Win32 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Release|x64.ActiveCfg = Release|x64 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Release|x64.Build.0 = Release|x64 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Release|x86.ActiveCfg = Release|Win32 + {BAA96EFE-86CD-47EA-8D5B-CAF1CC77BDC6}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E04AA2D6-0453-4D15-9DFB-2771EC700397} + EndGlobalSection +EndGlobal diff --git a/LinkListOperation/LinkListOperation.vcxproj b/LinkListOperation/LinkListOperation.vcxproj new file mode 100644 index 0000000..b2749c2 --- /dev/null +++ b/LinkListOperation/LinkListOperation.vcxproj @@ -0,0 +1,138 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 17.0 + Win32Proj + {baa96efe-86cd-47ea-8d5b-caf1cc77bdc6} + LinkListOperation + 10.0 + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + + + + + + + + + + + + + + + + + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + + + + + + + + \ No newline at end of file diff --git a/LinkListOperation/LinkListOperation.vcxproj.filters b/LinkListOperation/LinkListOperation.vcxproj.filters new file mode 100644 index 0000000..08fad02 --- /dev/null +++ b/LinkListOperation/LinkListOperation.vcxproj.filters @@ -0,0 +1,27 @@ + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + 头文件 + + + + + 源文件 + + + \ No newline at end of file diff --git a/LinkListOperation/main.cpp b/LinkListOperation/main.cpp new file mode 100644 index 0000000..1e50c6a --- /dev/null +++ b/LinkListOperation/main.cpp @@ -0,0 +1,105 @@ +#include +using namespace std; +#include "LinkList.h" +template +bool CreateOrderedList(LNode
*& L, int n) +{ + int i; + LNode
* p, * s; + p = L; + cout << "依次输入" << n << "个数据元素:" << endl; + for (i = 1; i <= n; i++) + { + s = new LNode
; + if (!s) return false; + cin >> s->data; + if (s->data >= p->data || p == NULL) + { + s->next = p->next; + p->next = s; + p = s; + } + else i--; + } + return true; +} +template +void InsertElementToOrderedList(LNode
*& L, int n, int length) +{ + LNode
* p; + p = L->next; + for (int i = 1; i <= length; i++) + { + if ((p->data) > n) + { + InsertElem_i(L, i, n); + break; + } + else if (p->next == NULL) + { + InsertElem_i(L, i + 1, n); + break; + } + else p = p->next; + } +} +template +void MergeTwoOrderedLists(LNode
*& L1, LNode
*& L2) +{ + LNode
* p, * q, * s; + p = L1->next; + q = L1->next->next; + s = L2->next; + while (!ListEmpty(L2)) + { + if (q == NULL) + { + p->next = s; + return; + } + else if ((q->data) >= (s->data) && (p->data) <= (s->data)) + { + int n = s->data; + LNode
* t; + t = s->next; + s->next = q; + p->next = s; + s = t; + if (s == NULL) return; + p = p->next; + } + else + { + p = p->next; + q = q->next; + } + } +} +int main() +{ + // Task 1: Create an ordered list + LNode* L; + InitList(L); + int length; + cout << "请输入有序表的长度: "; + cin >> length; + CreateOrderedList(L, length); + DispList(L); + // Task 2: Insert a new element and keep the list ordered + int n; + cout << "请输入插入有序表的元素: "; + cin >> n; + InsertElementToOrderedList(L, n, length); + DispList(L); + // Task 3: Merge two ordered linked list + LNode* L2; + InitList(L2); + int length2; + cout << "请输入另一个有序表的长度: "; + cin >> length2; + CreateOrderedList(L2, length2); + DispList(L2); + MergeTwoOrderedLists(L, L2); + DispList(L); + return 0; +} \ No newline at end of file