线性表--链式描述(一)
2016-06-06 00:00
344 查看
摘要: 单向链表
![](http://static.oschina.net/uploads/space/2016/0606/100523_EwUQ_2368202.png)
![](http://static.oschina.net/uploads/space/2016/0606/102218_Pemc_2368202.png)
![](http://static.oschina.net/uploads/space/2016/0606/102256_9qjU_2368202.png)
线性表的抽象类:
异常处理:
带头节点的循环链表 http://my.oschina.net/daowuming/blog/691504
单链表的基本操作
线性表的链式描述
![](http://static.oschina.net/uploads/space/2016/0606/100523_EwUQ_2368202.png)
单链表的插入操作
![](http://static.oschina.net/uploads/space/2016/0606/102218_Pemc_2368202.png)
单链表的删除操作
![](http://static.oschina.net/uploads/space/2016/0606/102256_9qjU_2368202.png)
单链表的实现
单链表类的实现:[code=language-cpp]//chain.hpp //-线性表链式描述 //-单链表 #pragma once #include <iostream> #include <ostream> #include <sstream> #include "linearList.h" #include "illegalIndex.hpp" //链表节点的结构定义 template <typename T> struct chainNode { T element; chainNode<T> *next; //methods chainNode() {} chainNode(const T& element) { this->element = element; } chainNode(const T& element, chainNode<T>* next) { this->element = element; this->next = next; } }; //单链表chain类 template <typename T> class chain : linearList<T> { public: //constructor chain(); chain(const chain<T>&); ~chain(); //ADT bool empty() const { return listSize == 0; } int size() const { return listSize; } T& get(int theIndex) const; int indexOf(const T& theElement) const; void erase(int theIndex); void clear(); void insert(int theIndex, const T& theElement); void insert_back(const T& theElement); void output(std::ostream& out) const; private: void checkIndex(int theIndex) const; chainNode<T> *firstNode, *lastNode; int listSize; }; template <typename T> chain<T>::chain() :listSize(0), firstNode(NULL), lastNode(NULL) { } //复制构造函数 template <typename T> chain<T>::chain(const chain<T>& theList) { this->listSize = theList.listSize; //链表为空 if (listSize == 0) { firstNode = lastNode = NULL; return; } //链表非空 //复制首元素 chainNode<T>* sourceNode = theList.firstNode; firstNode = new chainNode<T>(sourceNode->element); sourceNode = sourceNode->next; chainNode<T>* targetNode = firstNode; //复制剩余元素 while (sourceNode != NULL) { targetNode->next = new chainNode<T>(sourceNode->element); targetNode = targetNode->next; sourceNode = sourceNode->next; } targetNode->next = NULL; lastNode = targetNode; } //链表析构函数,删除链表所有节点 template <typename T> chain<T>::~chain() { while (firstNode != NULL) { chainNode<T>* nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } } //确定索引theIndex在0和listSize-1之间 template <typename T> void chain<T>::checkIndex(int theIndex) const { if (theIndex < 0 || theIndex >= listSize) { throw illegalIndex("theIndex out of range"); } } //return an element of theIndex //if not exists, throw exception template <typename T> T& chain<T>::get(int theIndex) const { checkIndex(theIndex); chainNode<T>* currentNode = firstNode; for (int i = 0; i < theIndex; ++i) { currentNode = currentNode->next; } return currentNode->element; } //return index of the element that first appeared //if element not exist,return -1 template <typename T> int chain<T>::indexOf(const T& theElement) const { chainNode<T>* currentNode = firstNode; int index = 0; while (currentNode != NULL && currentNode->element != theElement) { currentNode = currentNode->next; index++; } if (currentNode == NULL) { return -1; } else { return index; } } //删除索引为theIndex的元素 //若不存在,则抛出异常 template <typename T> void chain<T>::erase(int theIndex) { checkIndex(theIndex); chainNode<T>* deleteNode; if (theIndex == 0) { deleteNode = firstNode; firstNode = firstNode->next; } else { //用p指向要删除节点的前驱节点 chainNode<T>* p = firstNode; for (int i = 0; i < theIndex - 1; ++i) { p = p->next; } deleteNode = p->next; p->next = p->next->next; if (theIndex == (listSize - 1)) { lastNode = p; } } listSize--; delete deleteNode; } //删除所有的节点 template <typename T> void chain<T>::clear() { while (firstNode != NULL) { chainNode<T>* nextNode = firstNode->next; delete firstNode; firstNode = nextNode; } lastNode = firstNode; listSize = 0; } //在索引为TheIndex的位置上插入元素TheElement template <typename T> void chain<T>::insert(int theIndex, const T& theElement) { //索引无效 if (theIndex < 0 || theIndex > listSize) { ostringstream s; s << "error: list size = " << listSize; throw illegalIndex(s.str()); } if (theIndex == 0) { firstNode = new chainNode<T>(theElement, firstNode); lastNode = firstNode; } else { //寻找新元素前驱 chainNode<T>* p = firstNode; for (int i = 0; i < theIndex - 1; ++i) { p = p->next; } p->next = new chainNode<T>(theElement, p->next); if (theIndex == listSize) { lastNode = p->next; } else { } } listSize++; } //在链表末尾插入元素为TheElement的节点 template <typename T> void chain<T>::insert_back(const T& theElement) { chainNode<T>* newNode = new chainNode<T>(theElement, NULL); if (firstNode == NULL) { firstNode = lastNode = newNode; } else { lastNode->next = newNode; lastNode = newNode; } listSize++; } //把链表放入输入流 template <typename T> void chain<T>::output(std::ostream& out) const { for (chainNode<T>* currentNode = firstNode; currentNode != NULL; currentNode = currentNode->next) { out << currentNode->element << " "; } } //重载<< template <typename T> std::ostream& operator<< (std::ostream& out, const chain<T>& x) { x.output(out); return out; }
线性表的抽象类:
[code=language-cpp]//linearList.h //-线性表的抽象类 #pragma once #include <ostream> template <class T> class linearList { public: //return ture, only if the linear list is empty virtual bool empty() const = 0; //return the numbers of element of linear list virtual int size() const = 0; //return an element of index for theIndex virtual T& get(int theIndex) const = 0; //return an index of the theElement for first appearence positon virtual int indexOf(const T& theElement) const = 0; //delete an element of index for theIndex virtual void erase(int theIndex) = 0; //delete all node of a list virtual void clear() = 0; //insert theElement into position for index is theIndex in the linear list virtual void insert(int theIndex, const T& theElement) = 0; //insert the linearlist into the ostream out virtual void output(std::ostream& out) const = 0; };
异常处理:
[code=language-cpp]//illegalIndex.hpp //-索引异常类 #pragma once #include <string> #include <iostream> class illegalIndex { public: illegalIndex() { std::cerr << "illegal index value" << std::endl; } illegalIndex(std::string theMessage) { std::cerr << theMessage << std::endl; } };
带头节点的循环链表 http://my.oschina.net/daowuming/blog/691504
相关文章推荐
- C#数据结构之顺序表(SeqList)实例详解
- Lua教程(七):数据结构详解
- 解析从源码分析常见的基于Array的数据结构动态扩容机制的详解
- C#数据结构之队列(Quene)实例详解
- C#数据结构揭秘一
- C#定义并实现单链表实例解析
- C#数据结构之单链表(LinkList)实例详解
- 数据结构之Treap详解
- C语言实现单链表逆序与逆序输出实例
- 用C语言举例讲解数据结构中的算法复杂度结与顺序表
- C#数据结构之堆栈(Stack)实例详解
- C语言单链表常见操作汇总
- C#数据结构之双向链表(DbLinkList)实例详解
- JavaScript数据结构和算法之图和图算法
- Java数据结构及算法实例:冒泡排序 Bubble Sort
- C数据结构之单链表详细示例分析
- Java数据结构及算法实例:插入排序 Insertion Sort
- Java数据结构及算法实例:考拉兹猜想 Collatz Conjecture
- java数据结构之java实现栈
- 【数据结构与算法】数组应用4:多项式计算Java版