链表描述
来源:互联网 发布:webdriver 执行js 编辑:程序博客网 时间:2024/05/29 16:55
在链表描述中,数据对象实例的每个元素都放在单元或节点中进行描述。不过,节点不必是一个数组元素,因此没有什么公式可用来定位某个元素。取而代之的是,每个节点中都包含了与该节点相关的其他节点的位置信息。这种关于其他节点的位置信息被称之为链或指针。
图中的每个链表节点都正好有一个链接域,所以该图的链表结构被称之为单向链表(singly linked list)。
第一个节点
线性表的链表描述不需要指定表的最大长度。
用链表实现线性表
删除节点
插入节点
#pragma oncetemplate <class T>class ChainNode{ friend Chain<T>;private: T data; ChainNode<T> *link;};template<class T>class Chain{public: Chain() { first = 0; last = 0} ~Chain(); bool IsEmpty() const { return first == 0; } int Length() const; bool Find(int k, T& x) const; int Search(const T& x) const; Chain<T>& Delete(int k, T& x); Chain<T>& Insert(int k, const T& x); void Output(ostream& out) const; void Erase(); void Zero() { first = 0; } //类内定义,可能是内联函数,这种编程风格不好? Chain<T>& Append(const T& x)private: ChainNode<T> *first; //指向第一个节点的指针 ChainNode<T> *last; //指向最后一个节点的指针};template<class T>Chain<T>::~Chain(){ // 链表的析构函数,用于删除链表中的所有节点 last = 0; ChainNode<T> *next; // 下一个节点 while (first) { next = first->link; delete first; first = next; }}template<class T>int Chain<T>::Length() const{ // 返回链表中的元素总数 ChainNode<T> *current = first; int len = 0; while (current) { len++; current = current->link; } return len;}template<class T>bool Chain<T>::Find(int k, T& x) const{ //寻找链表中的第k个元素,并将其传送至x //如果不存在第k个元素,则返回false,否则返回true if (k < 1) return false; ChainNode<T> *current = first; int index = 1; // current的索引 while (index < k && current) { current = current->link; index++; } if (current) { x = current->data; return true; } return false; // 不存在第k个元素}template<class T>int Chain<T>::Search(const T& x) const{ //本函数假定对于类型T定义了 != 操作 //寻找x,如果发现x,则返回x的地址 //如果x不在链表中,则返回0 ChainNode<T> *current = first; int index = 1; // current的索引 while (current && current->data != x) { current = current->link; index++; } if (current) return index; return 0;}template<class T>void Chain<T>::Output(ostream& out) const{ //本函数要求对于类型T必须定义<<操作 //将链表元素送至输出流 ChainNode<T> *current; for (current = first; current; current = current->link) out << current->data << " ";}// 重载<<template <class T>ostream& operator<<(ostream& out, const Chain<T>& x){ //用法就是,cout << L (L是一个Chain链表), //从这里触发对Output()的调用,所以Output()是一个实用函数。 x.Output(out); return out;}template<class T>Chain<T>& Chain<T>::Delete(int k, T& x){ //把第k个元素取至x,然后从链表中删除第k个元素 //如果不存在第k个元素,则引发异常OutOfBounds if (k < 1 || !first) throw OutOfBounds(); // 不存在第k个元素 // p最终将指向第k个节点 ChainNode<T> *p = first; // 将p移动至第k个元素,并从链表中删除该元素 if (k == 1) // p已经指向第k个元素 first = first->link; // 删除之 else { //用q指向第k - 1个元素 ChainNode<T> *q = first; for (int index = 1; index < k - 1 && q; index++) q = q->link; if (!q || !q->link) throw OutOfBounds(); //不存在第k个元素 p = q->link; //存在第k个元素 if (p == last) last = q; //对last指针的一种可能处理, //如果刚好删除最后一个元素 q->link = p->link; //从链表中删除该元素,如果p指向最后一个节点, //则此处保证q->link=NULL } //保存第k个元素并释放节点p x = p->data; delete p; return *this;}template<class T>Chain<T>& Chain<T>::Insert(int k, const T& x){ //在第k个元素之后插入x //如果不存在第k个元素,则引发异常OutOfBounds //如果没有足够的空间,则传递NoMem异常 if (k < 0) throw OutOfBounds(); //p最终将指向第k个节点 ChainNode<T> *p = first; //将p移动至第k个元素 for (int index = 1; index < k && p; index++) p = p->link; if (k > 0 && !p) throw OutOfBounds(); //不存在第k个元素 //插入 ChainNode<T> *y = new ChainNode<T>; y->data = x; if (k) { //在p之后插入 y->link = p->link; //如果实在最后插入元素, //那么此处可以保证y->link=NULL p->link = y; } else { //作为第一个元素插入 y->link = first; first = y; } if (!y->link) last = y; //对last指针的一种可能处理, //如果刚好在最后的位置插入元素 return *this;}template<class T>void Chain<T>::Erase(){ //删除链表中的所有节点 last = 0; ChainNode<T> *next; while (first) { next = first->link; delete first; first = next; }}template<class T>Chain<T>& Chain<T>::Append(const T& x){ // 在链表尾部添加x ChainNode<T> *y; y = new ChainNode<T>; y->data = x; y->link = 0; if (first) { //链表非空 last->link = y; last = y; } else //链表为空 first = last = y; return *this;}//假定Output()不是Chain类的成员函数,并且在该类中没有重载操作符<<。//链表遍历器类template<class T>class ChainIterator {public: T* Initialize(const chain<T>& c) { location = c.first; if (location) return &location->data; return 0; } T* Next() { if(!location) return 0; location = location->link; if (location) return &location->data; return 0; }private: ChainNode<T> *location;};//采用以上链表遍历器输出链表//int *x;//ChainIterator<int> c;//x = c.Initialize(X);//while (x) {// cout << *x << ' ';// x = c.Next();//}//cout << endl;
循环链表
在带有头节点的循环链表中进行查找
template<class T>int CircularList<T>::Search(const T& x) const{ //在带有头节点的循环链表中寻找x ChainNode<T> *current = first->link; int index = 1; // current的索引 first->data = x; // 把x放入头节点 // 查找x while (current->data != x) { current = current->link; index++; } // 是链表表头吗? return ((current == first) ? 0 : index);}
双向链表
双向链表的类定义
template <class T>class DoubleNode { friend Double<T>;private: T data; DoubleNode<T> *left, *right;};template<class T>class Double {public: Double() { LeftEnd = RightEnd = 0; }; ~Double(); int Length() const; bool Find(int k, T& x) const; int Search(const T& x) const; Double<T>& Delete(int k, T& x); Double<T>& Insert(int k, const T& x); void Output(ostream& out) const;private: DoubleNode<T> *LeftEnd, *RightEnd;};
以上内容整理自网络电子资料,仅供学习交流用,勿作商业用途。转载请注明来源。
阅读全文
0 0
- 链表描述
- python描述双向链表
- 描述表
- 线性表的链表描述
- 链表的Java语言描述
- c描述双向链表删除结
- 链表的实现(Java语言描述)
- java描述链表基本操作
- 常用链表题目汇总,java描述
- python描述单向循环链表
- 80386简介--描述段描述符表
- 描述符表和描述符高速缓存
- 描述符表和描述符高速缓存
- 描述符表和描述符高速缓存
- 描述符表和描述符高速缓存
- 编程等级描述表
- 活动联接描述表
- 设备描述表(DC)
- 台湾大学林轩田机器学习技法课程学习笔记4 -- Soft-Margin Support Vector Machine
- ui的各种错误
- Android-25种开源炫酷动画框架
- OpenCV学习一:VS2010 + OpenCv2.4.9 的安装与配置
- Sublime使用汇总
- 链表描述
- git远程命令
- tar,bzip2,gzip,xz
- angularJS之 ionic安装配置
- ubuntu OpenJDK包名称
- Object 与 Class 中的方法
- 双系统进入ubuntu错误:Kernel Panic – not syncing: VFS: Unable to mount root fs on unknown-block
- 华为机试:求int型数据在内存中存储时1的个数、 取近似值
- 【Reading Notes】CP4-Physically Based Rendering in Unity5 (基于物理的渲染)