链表(C++)
来源:互联网 发布:建信优化基金530oo5 编辑:程序博客网 时间:2024/06/05 07:05
链表基本操作
- 生成链表
- 插入结点
- 查找结点
- 删除结点
- 遍历链表
- 清空链表
//// test.h// XCODE//// Created by vassago // #ifndef Node_h#define Node_h//类模板的定义template <class T>class Node {private: Node<T> *next; //指向后继结点的指针public: T data; //数据域 Node (const T &data, Node<T> *next = 0); //构造函数 void insertAfter(Node<T> *p); //在本结点之后插入一个同类结点p Node<T> *deleteAfter(); //删除本结点的后继结点,并返回其地址 Node<T> *nextNode(); //获取后继结点的地址 const Node<T> *nextNode() const; //获取后继结点的地址};//类的实现部分//构造函数,初始化数据和指针成员template <class T>Node<T>::Node(const T& data, Node<T> *next ) : data(data), next(next) { }//返回后继结点的指针template <class T>Node<T> *Node<T>::nextNode() { return next;}//返回后继结点的指针template <class T>const Node<T> *Node<T>::nextNode() const { return next;}//在当前结点之后插入一个结点ptemplate <class T>void Node<T>::insertAfter(Node<T> *p) { p->next = next; //p结点指针域指向当前结点的后继结点 next = p; //当前结点的指针域指向p}//删除当前结点的后继结点,并返回其地址template <class T> Node<T> *Node<T>::deleteAfter() { Node<T> *tempPtr = next;//将欲删除的结点地址存储到tempPtr中 if (next == 0) //如果当前结点没有后继结点,则返回空指针 return 0; next = tempPtr->next;//使当前结点的指针域指向tempPtr的后继结点 return tempPtr; //返回被删除的结点的地址}#endif /* Node_h */
#include<iostream>#include "Node.h"using namespace std;typedef long long LL;template<typename T>class LinkedList {private: //数据成员: Node<T> *front, *rear; //表头和表尾指针 Node<T> *prevPtr, *currPtr; //记录表当前遍历位置的指针,由插入和删除操作更新 int size; //表中的元素个数 int position; //当前元素在表中的位置序号。由函数reset使用 //函数成员: //生成新结点,数据域为item,指针域为ptrNext Node<T> *newNode(const T &item,Node<T> *ptrNext=NULL); //释放结点 void freeNode(Node<T> *p); //将链表L 拷贝到当前表(假设当前表为空)。 //被拷贝构造函数、operator = 调用 void copy(const LinkedList<T>& L);public: LinkedList(); //构造函数 LinkedList(const LinkedList<T> &L); //拷贝构造函数 ~LinkedList(); //析构函数 LinkedList<T> & operator = (const LinkedList<T> &L); //重载赋值运算符 int getSize() const; //返回链表中元素个数 bool isEmpty() const; //链表是否为空 void reset(int pos = 0);//初始化游标的位置 void next(); //使游标移动到下一个结点 bool endOfList() const; //游标是否到了链尾 int currentPosition() const; //返回游标当前的位置 void insertFront(const T &item); //在表头插入结点 void insertRear(const T &item); //在表尾添加结点 void insertAt(const T &item); //在当前结点之前插入结点 void insertAfter(const T &item); //在当前结点之后插入结点 T deleteFront(); //删除头结点 void deleteCurrent(); //删除当前结点 T& data(); //返回对当前结点成员数据的引用 const T& data() const; //返回对当前结点成员数据的常引用 //清空链表:释放所有结点的内存空间。被析构函数、operator= 调用 void clear();};template <class T> //生成新结点Node<T> *LinkedList<T>::newNode(const T& item, Node<T>* ptrNext){ Node<T> *p; p = new Node<T>(item, ptrNext); if (p == NULL) { cout << "Memory allocation failure!\n"; exit(1); } return p;}template <class T>void LinkedList<T>::freeNode(Node<T> *p) //释放结点{ delete p;}template <class T>void LinkedList<T>::copy(const LinkedList<T>& L) //链表复制函数{ Node<T> *p = L.front; //P用来遍历L int pos; while (p != NULL) //将L中的每一个元素插入到当前链表最后 { insertRear(p->data); p = p->nextNode(); } if (position == -1) //如果链表空,返回 return; //在新链表中重新设置prevPtr和currPtr prevPtr = NULL; currPtr = front; for (pos = 0; pos != position; pos++) { prevPtr = currPtr; currPtr = currPtr->nextNode(); }}template <class T> //构造一个新链表,将有关指针设置为空,size为0,position为-1LinkedList<T>::LinkedList() : front(NULL), rear(NULL),prevPtr(NULL), currPtr(NULL), size(0), position(-1){}template <class T>LinkedList<T>::LinkedList(const LinkedList<T>& L) //拷贝构造函数{ front = rear = NULL; prevPtr = currPtr = NULL; size = 0; position = -1; copy(L);}template <class T>LinkedList<T>::~LinkedList() //析构函数{ clear();}template <class T>LinkedList<T>& LinkedList<T>::operator=(const LinkedList<T>& L)//重载"="{ if (this == &L) // 不能将链表赋值给它自身 return *this; clear(); copy(L); return *this;}template <class T>int LinkedList<T>::getSize() const //返回链表大小的函数{ return size;}template <class T>bool LinkedList<T>::isEmpty() const //判断链表为空否{ return size == 0;}template <class T>void LinkedList<T>::reset(int pos) //将链表当前位置设置为pos{ int startPos; if (front == NULL) // 如果链表为空,返回 return; if (pos < 0 || pos > size - 1) // 如果指定位置不合法,中止程序 { std::cerr << "Reset: Invalid list position: " << pos << endl; return; } // 设置与遍历链表有关的成员 if (pos == 0) // 如果pos为0,将指针重新设置到表头 { prevPtr = NULL; currPtr = front; position = 0; } else // 重新设置 currPtr, prevPtr, 和 position { currPtr = front->nextNode(); prevPtr = front; startPos = 1; for (position = startPos; position != pos; position++) { prevPtr = currPtr; currPtr = currPtr->nextNode(); } }}template <class T>void LinkedList<T>::next() //将prevPtr和currPtr向前移动一个结点{ if (currPtr != NULL) { prevPtr = currPtr; currPtr = currPtr->nextNode(); position++; }}template <class T>bool LinkedList<T>::endOfList() const // 判断是否已达表尾{ return currPtr == NULL;}template <class T>int LinkedList<T>::currentPosition() const // 返回当前结点的位置{ return position;}template <class T>void LinkedList<T>::insertFront(const T& item) // 将item插入在表头{ if (front != NULL) // 如果链表不空则调用Reset reset(); insertAt(item); // 在表头插入}template <class T>void LinkedList<T>::insertRear(const T& item) // 在表尾插入结点{ Node<T> *nNode; prevPtr = rear; nNode = newNode(item); // 创建新结点 if (rear == NULL) // 如果表空则插入在表头 front = rear = nNode; else { rear->insertAfter(nNode); rear = nNode; } currPtr = rear; position = size; size++;}template <class T>void LinkedList<T>::insertAt(const T& item) // 将item插入在链表当前位置{ Node<T> *nNode; if (prevPtr == NULL) // 插入在链表头,包括将结点插入到空表中 { nNode = newNode(item, front); front = nNode; } else // 插入到链表之中. 将结点置于prevPtr之后 { nNode = newNode(item); prevPtr->insertAfter(nNode); } if (prevPtr == rear) //正在向空表中插入,或者是插入到非空表的表尾 { rear = nNode; //更新rear position = size; //更新position } currPtr = nNode; //更新currPtr size++; //使size增值}template <class T>void LinkedList<T>::insertAfter(const T& item) // 将item 插入到链表当前位置之后{ Node<T> *p; p = newNode(item); if (front == NULL) // 向空表中插入 { front = currPtr = rear = p; position = 0; } else // 插入到最后一个结点之后 { if (currPtr == NULL) currPtr = prevPtr; currPtr->insertAfter(p); if (currPtr == rear) { rear = p; position = size; } else position++; prevPtr = currPtr; currPtr = p; } size++; // 使链表长度增值}template <class T>T LinkedList<T>::deleteFront() // 删除表头结点{ T item; reset(); if (front == NULL) { cerr << "Invalid deletion!" << endl; exit(1); } item = currPtr->data; deleteCurrent(); return item;}template <class T>void LinkedList<T>::deleteCurrent() // 删除链表当前位置的结点{ Node<T> *p; if (currPtr == NULL) // 如果表空或达到表尾则出错 { cerr << "Invalid deletion!" << endl; exit(1); } if (prevPtr == NULL) // 删除将发生在表头或链表之中 { p = front; // 保存头结点地址 front = front->nextNode(); //将其从链表中分离 } else //分离prevPtr之后的一个内部结点,保存其地址 p = prevPtr->deleteAfter(); if (p == rear) // 如果表尾结点被删除 { rear = prevPtr; //新的表尾是prevPtr position--; //position自减 } currPtr = p->nextNode(); // 使currPtr越过被删除的结点 freeNode(p); // 释放结点,并 size--; //使链表长度自减}template <class T>T& LinkedList<T>::data() //返回一个当前结点数值的引用{ if (size == 0 || currPtr == NULL) // 如果链表为空或已经完成遍历则出错 { cerr << "Data: invalid reference!" << endl; exit(1); } return currPtr->data;}template <class T>void LinkedList<T>::clear() //清空链表{ Node<T> *currPosition, *nextPosition; currPosition = front; while (currPosition != NULL) { nextPosition = currPosition->nextNode(); //取得下一结点的地址 freeNode(currPosition); //删除当前结点 currPosition = nextPosition; //当前指针移动到下一结点 } front = rear = NULL; prevPtr = currPtr = NULL; size = 0; position = -1;}
//test_mainint main(){ LinkedList<int> list; list.insertAt(1); list.insertAfter(2); list.insertRear(3); list.insertFront(4); while(!list.isEmpty()){ cout<<list.data()<<endl; list.deleteCurrent(); } return 0;}
0 0
- 链表(C语言)
- 链表 例程(C++)
- 链表(C实现)
- 链表(C语言)
- C语言(链表)
- 链表(C++)
- 数据结构--链表(C++)
- 链表(C语言)
- 内存整理(C/C++)
- (C/C++)
- 内存整理(C/C++)
- 密码学(C/C++)
- C&C++)试题
- utilities(C/C++)
- c/c++(二)
- 链表(C语言数据结构)
- 浅谈C链表(1)
- 链表(C语言实现)
- Java反射分析.md
- tungsten replicator 代码的修改
- 冒泡排序法
- Intellij idea Hadoop 开发
- 数据结构--用C++实现顺序表
- 链表(C++)
- oracle 表数据被删 操作时误删除 误删数据 恢复方法
- Ubuntu下安装MySQL服务
- Ubuntu系列-Build first snap app--hello snap
- oracle 12Cwindows下安装使用基本
- Java练习题
- U盘容量变小如何解决
- 拦截器的执行顺序
- ajax实例