[C++]数据结构之单链表
来源:互联网 发布:residential 网络 编辑:程序博客网 时间:2024/05/16 09:40
2017/2/1 修改
/////////////////////////////////////// // LinkList.h : CLinkList 单链表类 // #include <assert.h> // 节点类 template <class Type> class CNode { // 方法 public : CNode() { m_pNext = 0; } // 属性 public : Type m_data; CNode * m_pNext; }; // 单链表类 template <class Type> class CLinkList { // 方法 public : // 构造 CLinkList(); CLinkList(Type arrInitial[], int iLen); // 析构 ~CLinkList(); // 销毁 void Destroy(); // 是否为空 bool IsEmpty(); // 取链表长度 int GetSize(); // 以序号查找节点(-1表示根节点, 超出链表范围返回尾结点) CNode<Type> * GetNodeFromID(int iIndex); CNode<Type> * operator [] (int iIndex); // 以内容查找节点 CNode<Type> * GetNodeFromData(Type data); // 以内容查找序号(失败返回-1) int Find(Type data); // 插入 bool AddAt(int iIndex, Type data); // 在末尾处加入 bool AddBack(Type data); // 删除 bool Delete(int iIndex); bool Delete(int iIndex, Type * data); // 属性 private : // 头结点,尾结点 CNode<Type> * m_pHead, * m_pTail; // 链表长度 int m_iSize; }; // 构造 template <class Type> CLinkList<Type>::CLinkList() { m_pHead = new CNode<Type>(); m_pTail = m_pHead; m_iSize = 0; } // 构造 template <class Type> CLinkList<Type>::CLinkList(Type arrInitial[], int iLen) { m_pHead = new CNode<Type>(); m_pTail = m_pHead; m_pHead->m_pNext = 0; m_iSize = 0; for (int i = 1; i <= iLen; i++) AddBack(arrInitial[i - 1]); } // 析构 template <class Type> CLinkList<Type>::~CLinkList() { Destroy(); delete m_pHead; } // 销毁 template <class Type> void CLinkList<Type>::Destroy() { CNode<Type> * p, * q; p = m_pHead; while(p) { q = p; p = p->m_pNext; delete q; } m_iSize = 0; } // 是否为空 template <class Type> bool CLinkList<Type>::IsEmpty() { return (!m_iSize); //return (m_pHead->m_pNext == 0); } // 以序号查找节点 template <class Type> CNode<Type> * CLinkList<Type>::GetNodeFromID(int iIndex) { // 我们经常会需要在链表尾部添加节点, // 如果频繁地使用 GetNodeFromID() 获取尾部节点,可能耗时较长, // 因此这样写 if (iIndex >= GetSize() - 1) return m_pTail; if (iIndex == -1) return m_pHead; assert(!IsEmpty()); if (IsEmpty()) return 0; assert(iIndex >= 0); assert(iIndex < GetSize()); if (iIndex < 0 || iIndex >= GetSize()) return 0; CNode<Type> * pTmp = m_pHead->m_pNext; while(pTmp && iIndex) { pTmp = pTmp->m_pNext; iIndex--; } return pTmp; } // 以内容查找节点 template <class Type> CNode<Type> * CLinkList<Type>::GetNodeFromData(Type data) { assert(!IsEmpty()); if (IsEmpty()) return 0; CNode<Type> * pTmp = m_pHead->m_pNext; while (pTmp) { if (pTmp->m_data != data) pTmp = pTmp->m_pNext; else return pTmp; } return 0; } // 以内容查找序号 template <class Type> int CLinkList<Type>::Find(Type data) { assert(!IsEmpty()); if (IsEmpty()) return 0; CNode<Type> * pTmp = m_pHead->m_pNext; int i = 0; while (pTmp) { if (pTmp->m_data != data) { pTmp = pTmp->m_pNext; i++; } else return i; } return -1; } // 取链表长度 template <class Type> int CLinkList<Type>::GetSize() { /* int iSize = 0; CNode<Type> * pTmp = m_pHead->m_pNext; while (pTmp) { iSize++; pTmp = pTmp->m_pNext; } return iSize; */ // 上面这种办法是可行的,但是有一个更简单的方法 return m_iSize; } // 以序号查找节点(运算符重载) template <class Type> CNode<Type> * CLinkList<Type>::operator [] (int iIndex) { return GetNodeFromID(iIndex); } // 插入 template <class Type> bool CLinkList<Type>::AddAt(int iIndex, Type data) { CNode<Type> * p, * pLast; pLast = GetNodeFromID(iIndex - 1); assert(pLast); if (!pLast) return false; p = new CNode<Type>(); p->m_data = data; p->m_pNext = pLast->m_pNext; pLast->m_pNext = p; if (iIndex == GetSize()) m_pTail = p; m_iSize++; return true; } // 在末尾处加入 template <class Type> bool CLinkList<Type>::AddBack(Type data) { return AddAt(GetSize(), data); } // 删除 template <class Type> bool CLinkList<Type>::Delete(int iIndex) { CNode<Type> * pLast, * p; pLast = GetNodeFromID(iIndex - 1); assert(pLast); if (!pLast) return false; p = pLast->m_pNext; assert(p); if (!p) return false; pLast->m_pNext = p->m_pNext; delete p; if (iIndex == GetSize()) m_pTail = pLast; m_iSize--; return true; } // 删除 template <class Type> bool CLinkList<Type>::Delete(int iIndex, Type * data) { *data = GetNodeFromID(iIndex) -> m_data; return Delete(iIndex); }
///////////////////////////////////////// test1.cpp : 测试程序 // 从A中去除B中已存在的元素,保存到C中//#include <iostream>#include <cstdio>#include "LinkList.h"using namespace std;int main(){int arrA[] = {1, 2, 3, 4, 5, 6, 7};int arrB[] = {5, 7, 8, 9};CLinkList<int> linkA(arrA, sizeof(arrA) / sizeof(int));CLinkList<int> linkB(arrB, sizeof(arrB) / sizeof(int));linkA.Delete(4);linkB.AddAt(3, 2);printf("单链表 A 中的元素个数:%d\n", linkA.GetSize());printf("");for (int i = 1; i <= linkA.GetSize(); i++)cout << linkA[i - 1]->m_data << " ";cout << endl;printf("单链表 B 中的元素个数:%d\n", linkB.GetSize());printf("");for (int i = 1; i <= linkB.GetSize(); i++)cout << linkB[i - 1]->m_data << " ";cout << endl;CLinkList<int> linkC;for (int i = 1; i <= linkA.GetSize(); i++){if (linkB.Find(linkA[i - 1]->m_data) == -1)linkC.AddBack(linkA[i - 1]->m_data);}printf("单链表 A - B 中的元素个数:%d\n", linkC.GetSize());printf("");for (int i = 1; i <= linkC.GetSize(); i++)cout << linkC[i - 1]->m_data << " ";cout << endl;return 0;}
///////////////////////////////////////// test2.cpp : 测试程序 // 合并链表 //#include <iostream>#include <cstdio>#include "LinkList.h"using namespace std;template <class Type>void PrintList(const char str[], CLinkList<Type> * list){printf("链表 %s 共有 %d 个元素:\n", str, list->GetSize());cout << "";for (int i = 1; i <= list->GetSize(); i++)cout << list->GetNodeFromID(i - 1)->m_data << " ";cout << endl;}int main(){int arr[] = {1, 8, 3, 4, 5};CLinkList<int> list1(arr, 5);PrintList("list1", &list1);int iData;list1.Delete(1, &iData);cout << endl << "删除链表中的第二个节点:" << iData << endl;PrintList("list1", &list1);cout << endl << "在第一个元素值等于4的节点前插入一个元素值为7的节点。" << endl;list1.AddAt(list1.Find(4), 7);PrintList("list1", &list1);cout << endl;int arr2[] = {9, 8, 6, 5};CLinkList<int> list2(arr2, 4);PrintList("list2", &list2);cout << endl << "把两条链表合并" << endl;for (int i = 1; i <= list2.GetSize(); i++)list1.AddBack(list2[i - 1]->m_data);PrintList("list1 + list2", &list1);}
-----------------------------------------------------------------------------------
下面是初始版本的代码:
不知道有没有错误。
///////////////////////////////////////// LinkList.h : CLinkList 单链表类 // #include <assert.h>// 节点类 template <class Type>class CNode {// 方法public :CNode(){m_pNext = 0;} // 属性 public :Type m_data;CNode * m_pNext;};// 单链表类template <class Type>class CLinkList {// 方法public :// 构造 CLinkList();CLinkList(Type arrInitial[], int iLen);// 析构~CLinkList();// 销毁 void Destroy();// 是否为空bool IsEmpty();// 取链表长度int GetSize();// 以序号查找节点(-1表示根节点) CNode<Type> * GetNodeFromID(int iIndex);CNode<Type> * operator [] (int iIndex);// 以内容查找节点 CNode<Type> * GetNodeFromData(Type data);// 以内容查找序号(失败返回-1)int Find(Type data);// 插入bool Insert(int iIndex, Type data);// 在末尾处加入 bool Add(Type data);// 删除bool Delete(int iIndex);bool Delete(int iIndex, Type * data); // 属性private :// 头结点 CNode<Type> * m_pHead; };// 构造template <class Type>CLinkList<Type>::CLinkList(){m_pHead = new CNode<Type>();m_pHead->m_pNext = 0;}// 构造template <class Type>CLinkList<Type>::CLinkList(Type arrInitial[], int iLen){m_pHead = new CNode<Type>();m_pHead->m_pNext = 0;for (int i = 1; i <= iLen; i++)Add(arrInitial[i - 1]);}// 析构template <class Type>CLinkList<Type>::~CLinkList(){Destroy();delete m_pHead;}// 销毁 template <class Type>void CLinkList<Type>::Destroy(){CNode<Type> * p, * q;p = m_pHead;while(p){q = p;p = p->m_pNext;delete q;}}// 是否为空template <class Type>bool CLinkList<Type>::IsEmpty(){return (m_pHead->m_pNext == 0);}// 以序号查找节点 template <class Type>CNode<Type> * CLinkList<Type>::GetNodeFromID(int iIndex){if (iIndex == -1)return m_pHead;assert(!IsEmpty());if (IsEmpty())return 0;assert(iIndex >= 0);assert(iIndex < GetSize());if (iIndex < 0 || iIndex >= GetSize())return 0;CNode<Type> * pTmp = m_pHead->m_pNext;while(pTmp && iIndex){pTmp = pTmp->m_pNext;iIndex--;}return pTmp;}// 以内容查找节点 template <class Type>CNode<Type> * CLinkList<Type>::GetNodeFromData(Type data){assert(!IsEmpty());if (IsEmpty())return 0;CNode<Type> * pTmp = m_pHead->m_pNext;while (pTmp){if (pTmp->m_data != data)pTmp = pTmp->m_pNext;elsereturn pTmp;}return 0;}// 以内容查找序号template <class Type>int CLinkList<Type>::Find(Type data){assert(!IsEmpty());if (IsEmpty())return 0;CNode<Type> * pTmp = m_pHead->m_pNext;int i = 0;while (pTmp){if (pTmp->m_data != data){pTmp = pTmp->m_pNext;i++;} elsereturn i;}return -1;} // 取链表长度template <class Type>int CLinkList<Type>::GetSize(){int iSize = 0;CNode<Type> * pTmp = m_pHead->m_pNext;while (pTmp){iSize++;pTmp = pTmp->m_pNext;}return iSize;}// 以序号查找节点(运算符重载)template <class Type>CNode<Type> * CLinkList<Type>::operator [] (int iIndex){return GetNodeFromID(iIndex);}// 插入template <class Type>bool CLinkList<Type>::Insert(int iIndex, Type data){CNode<Type> * p, * pLast;pLast = GetNodeFromID(iIndex - 1);assert(pLast);if (!pLast)return false;p = new CNode<Type>();p->m_data = data;p->m_pNext = pLast->m_pNext;pLast->m_pNext = p;return true;}// 在末尾处加入 template <class Type>bool CLinkList<Type>::Add(Type data){return Insert(GetSize(), data);}// 删除template <class Type>bool CLinkList<Type>::Delete(int iIndex){CNode<Type> * pLast, * p;pLast = GetNodeFromID(iIndex - 1);assert(pLast);if (!pLast)return false;p = pLast->m_pNext;assert(p);if (!p)return false;pLast->m_pNext = p->m_pNext;delete p;return true;}// 删除template <class Type>bool CLinkList<Type>::Delete(int iIndex, Type * data){*data = GetNodeFromID(iIndex) -> m_data;return Delete(iIndex);}
(顺便说一句,那个 GetNodeFromID() 和 GetNodeFromData() 不能写成重载函数,因为后者的参数 data 的类型有可能是 int )
测试代码(从A中去除B中已存在的元素,保存到C中):
#include <iostream>#include <cstdio>#include "LinkList.h"using namespace std;int main(){int arrA[] = {1, 2, 3, 4, 5, 6, 7};int arrB[] = {5, 7, 8, 9};CLinkList<int> linkA(arrA, sizeof(arrA) / sizeof(int));CLinkList<int> linkB(arrB, sizeof(arrB) / sizeof(int));linkA.Delete(4);printf("单链表 A 中的元素个数:%d\n", linkA.GetSize());printf("");for (int i = 1; i <= linkA.GetSize(); i++)cout << linkA[i - 1]->m_data << " ";cout << endl;printf("单链表 B 中的元素个数:%d\n", linkB.GetSize());printf("");for (int i = 1; i <= linkB.GetSize(); i++)cout << linkB[i - 1]->m_data << " ";cout << endl;CLinkList<int> linkC;for (int i = 1; i <= linkA.GetSize(); i++){if (linkB.Find(linkA[i - 1]->m_data) == -1)linkC.Add(linkA[i - 1]->m_data);}printf("单链表 A - B 中的元素个数:%d\n", linkC.GetSize());printf("");for (int i = 1; i <= linkC.GetSize(); i++)cout << linkC[i - 1]->m_data << " ";cout << endl;return 0;}
0 0
- C数据结构之单链表
- [C++]数据结构之单链表
- 数据结构之单链表(C++)
- c数据结构之单链表操作
- c语言数据结构之单链表
- linux C 数据结构之单链表
- 数据结构之单链表C语言实现
- 数据结构C语言之单链表简单实现
- 数据结构C语言实现之单链表
- 数据结构之单链表C++(模板)
- 数据结构之单链表实现栈(C++)
- 数据结构c语言实现之单链表
- 数据结构c语言实现之静态单链表
- 数据结构之---c语言实现单链表
- 数据结构之单链表实现(C++)
- 【数据结构之C语言实现】单链表
- C语言数据结构之单链表的拆分
- 数据结构之单链表常见操作 C
- NTP时间服务器实现Linux时间同步
- [LCT 主席树] BZOJ 3514 Codechef MARCH14 GERALD07加强版
- leecode 解题总结:21. Merge Two Sorted Lists
- 关于getChildFragmentManager()、 getFragmentManager()、getSupportFragmentManager()的使用
- 关于getChildFragmentManager()、 getFragmentManager()、getSupportFragmentManager()的使用
- [C++]数据结构之单链表
- 暂时用着,Android中的设计模式
- 富爸爸--财务自由之路
- LEETCODE--Single Number
- OpenWRT(九)DTS及串口
- Eclipse 修改项目名称
- 让 Anchor 属性拥有设计时行为
- Python输出\u编码将其转换成中文
- android 获取路径目录方法 以及 获取路径方法