C++模板实现链表
来源:互联网 发布:ubuntu 17.10 samba 编辑:程序博客网 时间:2024/06/14 15:39
单链表是一种非常基本的数据结构. 虽然C++ STL中已经存在功能强大的List,但我们通过自己实现单链表,对于锻炼C++的基本功,加深对编程的理解与认识还是很有益的. 另外,自己的代码,在使用过程中更容易和敢于修改,更容易灵活定制自己的需求.
在实现单链表的过程中,选用模板,可以使得链表得到极大的灵活性.代码的可复用性大大增强.
核心代码分析解读:
1. 定义存放单个节点的数据结构: T可以在调用过程中灵活变换数据类型(基本数据类型,该程序的T不能支持对象数据类型). data为存放的数据, next为指向的下一个节点.
template struct LinkNode
{
T data;
LinkNode* next;
};
2.在添加节点时,我们只传入值.在函数内部构造节点.注意用new来分配内存.之后先将新节点的next指向node后面的节点(假定在node后面插入节点),然后将node的next指向新生成的节点.顺序很重要.
LinkNode *linkNode = new LinkNode();
linkNode->data = data;
linkNode->next = node->next;
node->next = linkNode;
3. 在删除时,需要准备要删除的前驱节点进行记录.是前驱节点指向后继节点.之后可以删除当前节点.注意释放内存,避免内存泄露.之后将指针指向NULL,避免野指针.
preNode->next = needRemoveNode->next;
delete needRemoveNode;
needRemoveNode = NULL;
4. 在对象释放的时候,C++会自动调用析构函数.在析构函数中,要记得释放内存,与将指针置NULL.
LinkNode *iter = head;
LinkNode *preIter = iter;
while (NULL != preIter->next)
{
iter = preIter->next;
preIter->next = iter->next;
cout << iter->data << ” will be deleted in destruct function.” << endl;
delete iter;
iter = NULL;
}
5. C++使用模板时,要注意在调用时,同时要包含.h与.cpp文件.或者将模板函数实现也写在.h文件中(双刃剑). 与通常只包含.h文件不同. 另外,要注意代码改动后,有时候需要进行进行全部重新编译,这个是因为模板在实例化时会产生二次编译,仅使用增量编译有时会产生错误.
程序运行结果如下图:
C++头文件如下:
#ifndef _LINK_LIST_H_#define _LINK_LIST_H_#include "Constant.h"template<typename T> struct LinkNode{ T data; LinkNode* next;};template<typename T, const unsigned int capacity> class LinkList{public: LinkList(); ~LinkList(); bool isEmpty(); bool isFull(); bool insertFromHead(T data); bool insertAtLocation(T data, unsigned int n); bool deleteFromHead(); bool deleteFromHead(T& data); bool deleteAtLocation(unsigned int n); bool deleteViaData(T data); bool getFirst(T& data); unsigned int getSize(); void print();private: unsigned int linkNodeNum; LinkNode<T> *head = NULL;};#endif // !_LINK_LIST_H_
C++源文件如下:
#include "LinkList.h"#include <string>#include <iostream>using namespace std;template<typename T, const unsigned int capacity> LinkList<T, capacity>::LinkList(){ linkNodeNum = 0; head = new LinkNode<T>; head->next = NULL; memset(head, 0, sizeof(head));}template<typename T, const unsigned int capacity> LinkList<T, capacity>::~LinkList(){ LinkNode<T> *iter = head; LinkNode<T> *preIter = iter; while (NULL != preIter->next) { iter = preIter->next; preIter->next = iter->next; cout << iter->data << " will be deleted in destruct function." << endl; delete iter; iter = NULL; }}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::isEmpty(){ if (NULL == head->next) return true; return false;}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::isFull(){ if (capacity == linkNodeNum) return true; return false;}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::insertFromHead(T data){ if (NULL == head) { head = new LinkNode<T>; head->next = NULL; } if (isFull()) { return false; } LinkNode<T> *linkNode = new LinkNode<T>(); linkNode->data = data; linkNode->next = NULL; LinkNode<T> *afterNode = head->next; head->next = linkNode; linkNode->next = afterNode; linkNodeNum++; return true;}//Insert data after nth nodetemplate<typename T, const unsigned int capacity> bool LinkList<T, capacity>::insertAtLocation(T data, unsigned int n){ if (isFull()) return false; if (linkNodeNum < n) { return false; } else { //Insert after n LinkNode<T> *node = head; //Insert at last for (unsigned int i = 0; i < n; i++) { if (NULL != node->next) { node = node->next; } else { //need log the error return false; } } LinkNode<T> *linkNode = new LinkNode<T>(); linkNode->data = data; linkNode->next = node->next; node->next = linkNode; linkNodeNum++; } return true;}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::deleteFromHead(){ bool rs = false; if (isEmpty()) { rs = false; } else { LinkNode<T> *needRemoveNode = head->next; if (NULL == needRemoveNode) { rs = false; } else { LinkNode<T> *nextNode = needRemoveNode->next; head->next = nextNode; needRemoveNode->next = NULL; delete needRemoveNode; linkNodeNum--; rs = true; } } return rs;}template<typename T, const unsigned int capacity>bool LinkList<T, capacity>::deleteFromHead(T& data){ bool rs = false; if (isEmpty()) { rs = false; } else { LinkNode<T> *needRemoveNode = head->next; if (NULL == needRemoveNode) { rs = false; } else { data = needRemoveNode->data; LinkNode<T> *nextNode = needRemoveNode->next; head->next = nextNode; needRemoveNode->next = NULL; delete needRemoveNode; linkNodeNum--; rs = true; } } return rs;}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::deleteAtLocation(unsigned int n){ if (isEmpty()) { return false; } if (n > linkNodeNum) { return false; } else { LinkNode<T> *needRemoveNode = head; LinkNode<T> *preNode = NULL; for (unsigned int i = 0; i < n; i++) { preNode = needRemoveNode; needRemoveNode = needRemoveNode->next; if (NULL == needRemoveNode) { return false; } } preNode->next = needRemoveNode->next; delete needRemoveNode; needRemoveNode = NULL; linkNodeNum--; } return true;}template<typename T, const unsigned int capacity> bool LinkList<T, capacity>::deleteViaData(T data){ if (isEmpty()) { return false; } bool isFind = false; LinkNode<T> *iter = head; while(NULL != iter->next) { LinkNode<T> *preNode = iter; iter = iter->next; try { if (data == iter->data) { preNode->next = iter->next; delete iter; iter = NULL; isFind = true; linkNodeNum--; break; } } catch (exception e) { cout << e.what() << endl; return false; } } return isFind;}template <typename T, const unsigned int capacity>bool LinkList<T, capacity>::getFirst(T& data){ bool rs = false; if (isEmpty()) { rs = false; } else { if ((NULL == head) || (NULL == head->next)) { rs = false; } else { data = head->next->data; rs = true; } } return rs;}template<typename T, const unsigned int capacity>unsigned int LinkList<T, capacity>::getSize(){ return linkNodeNum;}template<typename T, const unsigned int capacity> void LinkList<T, capacity>::print(){ LinkNode<T>* iter = head; while (NULL != iter->next) { iter = iter->next; cout << iter->data << " "; } cout << endl;}
测试代码如下:
void testLinkList(){ LinkList<int,LINK_NODE_SIZE> *linkList = new LinkList<int, LINK_NODE_SIZE>(); linkList->insertFromHead(9); linkList->print(); linkList->insertFromHead(7); linkList->print(); linkList->insertAtLocation(8, 1); linkList->print(); linkList->insertAtLocation(6, 8); linkList->print(); linkList->insertAtLocation(5, 3); linkList->print(); linkList->insertFromHead(4); linkList->print(); linkList->insertFromHead(3); linkList->print(); linkList->deleteFromHead(); linkList->print(); linkList->deleteViaData(7); linkList->print(); linkList->deleteAtLocation(3); linkList->print(); linkList->deleteAtLocation(14); linkList->print(); linkList->deleteViaData(0); linkList->print(); linkList->deleteViaData(1.2); linkList->print(); delete linkList; linkList = NULL;}void testLinkList2(){ LinkList<string, LINK_NODE_SIZE> *linkList = new LinkList<string, LINK_NODE_SIZE>(); linkList->insertFromHead("AA"); linkList->print(); linkList->insertFromHead("BB"); linkList->print(); linkList->insertAtLocation("CC", 1); linkList->print(); linkList->insertAtLocation("DD", 8); linkList->print(); linkList->insertAtLocation("EE", 3); linkList->print(); linkList->insertFromHead("FF"); linkList->print(); linkList->insertFromHead("GG"); linkList->print(); linkList->deleteFromHead(); linkList->print(); linkList->deleteViaData("FF"); linkList->print(); linkList->deleteAtLocation(3); linkList->print(); linkList->deleteAtLocation(14); linkList->print(); linkList->deleteViaData("DDD"); linkList->print(); delete linkList; linkList = NULL;}
- [C++] 模板类实现简单链表
- <C/C++数据结构>双向链表(C++模板实现)
- 【C++】模板实现带头节点的双向循环链表
- [数据结构]链表的实现(c++/类模板)
- C 链表模板
- c++(模板类)实现顺序表
- 【C++】用模板实现顺序表
- 【C++】用模板实现顺序表Vector
- C语言实现stack模板
- C语言实现函数模板
- [c++]栈模板的实现
- c++::用模板实现List
- 【c++】模板实现动态Vector
- 链表的模板实现
- 链表的模板实现
- 类模板 实现链表
- //链表的模板实现
- 类模板 实现链表
- 7个碎片的excel重组实验
- 转接IC GM7150BC CVBS转BT 656 低功耗NTSC/PAL视频解码器
- Installing CUDA 8.0 + cuDNN 5.1 + TensorFlow with Ubuntu 14.04 (下)
- Java之对象的创建和使用的一个实例分析
- 如何定位性能瓶颈
- C++模板实现链表
- 海子的诗
- 安装STARMAN
- GYM 101149 D.Behind the Wall(最小割-Dinic)
- [蓝桥杯]-特殊回文数(java)
- IDEA 搭建SpringBoot
- COGS 577 蝗灾
- 排序算法2--简单选择排序、堆排序
- CCF 201503-1