C++数据结构与算法——单向循环链表
来源:互联网 发布:淘宝客服工作感想 编辑:程序博客网 时间:2024/06/04 18:53
单向循环链表:相对于单向链表的最后一个节点的next指针指向nullptr,单向循环链表的最后一个节点的next指针指向链表头。此处主要实现了单向循环链表的插入、删除、构造、析构、输出操作符等简单功能。
注意:单向循环链表最主要关心的是插入、删除时头节点的更新问题。如,在链表头删除时需要将链表头指向下一个节点或者置为nullptr。
单向循环链表实现:
#pragma once#include <iostream>using namespace std;template<typename T>struct ChainNode{ ChainNode<T> *next; T data; ChainNode(const T &t) { data = t; next = nullptr; } ChainNode(const ChainNode<T> & d):next(d.next),data(d.data){}};template<typename T>class CircularList{public: CircularList():m_head(nullptr),m_isize(0){} ~CircularList(); bool Insert(const T &t, const int n = 0); bool DeleteAt(T &t, const int n); bool IsEmpty() { return (m_isize == 0); } void AddBack(const T &t); ChainNode<T> *GetTail(); friend ostream &operator<< (ostream &os, const CircularList<T> & rhl) { ChainNode<T> *tmp = rhl.m_head; for (int i = 0; i < rhl.m_isize;++i) { os << tmp->data << " "; tmp = tmp->next; } return os << endl; }protected: ChainNode<T> *GetAt(const int n);private: ChainNode<T> *m_head; int m_isize;};// 删除第n个节点// 删除主要考虑的是,要将删除节点的前一节点和后一节点连接起来,要考虑删除头节点时更新头节点的情况template<typename T>bool CircularList<T>::DeleteAt(T &t, const int n){ if (n < 0 || n > m_isize - 1) { return false; } ChainNode<T> *tmp = GetAt(n); if (n == 0) { ChainNode<T> *tail = GetTail(); if (m_isize == 1) { m_head = nullptr; } else { m_head = tmp->next; tail->next = m_head; } } else { ChainNode<T> *prev = GetAt(n - 1); prev->next = tmp->next; } t = tmp->data; delete tmp; m_isize--; return true;}// 将t插入到第n个节点后,如果为空链表则调用addback// 插入主要考虑的是将第n个节点指向新节点,将新节点指向n+1个节点(当n为m_isize-1时需要指向m_head)template<typename T>bool CircularList<T>::Insert(const T &t, const int n){ if (IsEmpty()) { if (n == 0) { AddBack(t); return true; } return false; } // 插入的地方非法 if (n < 0 || n >= m_isize) { return false; } // 如果链表不为空,则有可以是在头、中、尾三个地方插入,以下代码满足三种情况 ChainNode<T> *tmp = GetAt(n); ChainNode<T> *next = tmp->next; ChainNode<T> *newnode = new ChainNode<T>(t); tmp->next = newnode; newnode->next = next; ++m_isize; return true;}template<typename T>ChainNode<T> * CircularList<T>::GetTail(){ return GetAt(m_isize - 1);}template<typename T>CircularList<T>::~CircularList(){ // 由于是单向循环链表,遍历时如果以指针是否为空或者指向head节点为结束条件都不合适,因此使用m_isize不为0为条件进行遍历 ChainNode<T> *tmp = m_head; while ( m_isize != 0) { tmp = m_head->next; delete m_head; m_head = tmp; --m_isize; }}template<typename T>inline void CircularList<T>::AddBack(const T & t){ ChainNode<T> * newnode = new ChainNode<T>(t); // 当前链表为空 if (m_head == nullptr) { m_head = newnode; m_head->next = m_head; ++m_isize; return; } // 链表不为空,则将最后一个节点指向新节点,新节点指向head节点 ChainNode<T> *tmp = GetTail(); tmp->next = newnode; newnode->next = m_head; ++m_isize; return;}template<typename T>ChainNode<T> * CircularList<T>::GetAt(const int n){ // 只能获取下标[0,m_isize - 1]的元素 if (n < 0 || n >= m_isize) { return nullptr; } ChainNode<T> * tmp = m_head; for (int i = 0;i < n;++i) { tmp = tmp->next; } return tmp;}
单向循环链表测试:
#include "stdafx.h"#include "CircularList.h"#include <iostream>using namespace std;int main(){ CircularList<int> *pnode = new CircularList<int>; pnode->AddBack(10); pnode->AddBack(15); pnode->AddBack(24); pnode->AddBack(36); cout << *pnode; pnode->Insert(1314, 1); cout << *pnode; // 10 15 1314 24 36 int iret = -1; pnode->AddBack(386);// 10 15 1314 24 36 386 pnode->DeleteAt(iret, 4);// delete 36 cout << *pnode; // 10 15 1314 24 386 return 0;}
阅读全文
1 0
- C++数据结构与算法——单向循环链表
- 数据结构(C++)——单向循环链表
- <数据结构与算法>单向循环链表基本框架(C语言描述)
- 数据结构——单向循环链表
- C语言基础—数据结构之单向循环链表和双向循环链表
- 数据结构与算法—循环链表
- 数据结构与算法(单向链表)
- 数据结构:循环单向链表——约瑟夫环
- c语言_数据结构_单向循环链表
- c语言数据结构之单向循环链表约瑟夫问题
- C——(单向、单向循环、双向、双向循环)链表学习总结
- 数据结构与算法(C语言版)__循环链表
- 数据结构与算法学习之路:简单的电话簿实现——单向链表
- 算法与数据结构-单向链表的基本操作C语言实现
- <数据结构与算法><C>单向链表结构设计学生信息管理系统——附:源码、简单的Makefile、思维导图
- 数据结构之单向循环链表
- 数据结构之单向循环链表
- 【数据结构】单向循环链表实现
- 2017读书计划
- 正则表达式
- vim编辑后 生成的2个文件 是什么?
- Mysql错误提示:Error: Duplicate entry '0' for key 'PRIMARY'
- 在Filezilla下用sftp上传文件
- C++数据结构与算法——单向循环链表
- 路由器桥接chinanet拨号共享
- javascript使用正则表达式入门
- 字符串的输入与访问
- JS高级---原型到原型链(一看就懂)
- opencv 鼠标操作 裁剪图片
- Linux下Memcache服务器端的安装
- oracle中关于undo表空间的使用
- Ajax