C++学习笔记48:链表的基本操作
//链表的基本操作
//生成链表,插入结点,查找结点,删除结点,遍历链表,清空链表
//链表类模板 //LinkedList.h
#ifndef LINKEDLIST_H
#define LINKEDLIST_H
#include "Node.h" template <class 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拷贝到当前表(假设当前表为空)
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 = );
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;
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 alloction failure!\n";
exit();
}
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;
int pos;
while (p != NULL)
{
insertRear(p->data);
p = p->nextNode();
}
if (position == -)
return;
prevPtr = NULL;
currPtr = front;
for (pos = ; pos != position; pos++)
{
prevPtr = currPtr;
currPtr = currPtr->nextNode();
}
} template <class T> LinkedList<T>::LinkedList() :front(NULL), rear(NULL),
prevPtr(NULL), currPtr(NULL), size(), position(-)
{ } template <class T> LinkedList<T>::LinkedList(const LinkList<T> &L)
{
front = rear = NULL;
prevPtr = currPtr = NULL;
size = ;
position = -;
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 == ;
} template <class T> void LinkedList<T>::reset(int pos)
{
int startPos;
if (front == NULL)
return;
if (pos < || pos > size - )
{
std::cerr << "Reset: Invalid list position:" << pos << endl;
return;
}
if (pos == )
{
prevPtr = NULL;
currPtr = front;
position = ;
}
else
{
currPtr = front->nextNode();
prevPtr = front;
startPos = ;
for (postion = startPos; position != pos; position)
{
prevPtr = currPtr;
currPtr = currPtr->nextNode();
}
}
} template <class T> void LinkedList<T>::next()
{
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>::insertFront(const T& item)
{
if (front != NULL)
reset();
insertAt(item);
} template <class T> void LinkedList<T>::insertRear(const T& item)
{
Node<T> *node;
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)
{
Node<T> *nNode;
if (prevPtr == NULL)
{
nNode = newNode(item, front);
front = nNode;
}
else
{
nNode = newNode(item);
prevPtr->insertAfter(nNode);
}
if (prevPtr == rear)
{
rear = nNode;
position = size;
}
currPtr = nNode;
size++;
} template <class T> void LinkedList<T>::insertAfter(const T& item)
{
Node<T> *p;
p = newNode(item);
if (front == NULL)
{
front = currPtr = rear = ;
position = ;
}
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();
}
item = currPtr->data;
deleteCurrent();
return item;
} template <class T> void LinkedList<T>::deleteCurrent()
{
Node<T> *p;
if (currPtr == NULL)
{
cerr << "Invalid deletion !" << endl;
exit();
}
if (prevPtr == NULL)
{
p = front;
front = front->nextNode();
}
else
p = prevPtr->deleteAfter();
if (p == rear)
{
rear = prePtr;
position--;
}
currPtr = p->nextNode();
freeNode(p);
size--;
} template <class T> T & LinkedList<T>::data()
{
if (size == || currPtr == NULL)
{
cerr << "Data:invalid reference!" << endl;
exit();
}
return currPtr->data;
} template <class T> void LinkedList<T>::clear()
{
Node<T> *currPosition, *nextPosition;
currentPosition = front;
while (currentPosition != NULL)
{
nextPosition = currentPosition->nextNode();
freeNode(currentPosition);
currentPosition = nextPosition;
}
front = rear = NULL;
prevPtr = currPtr = NULL;
size = ;
position = -;
} #endif // !LINKEDLIST_H
C++学习笔记48:链表的基本操作的更多相关文章
- html5标签video(播放器)学习笔记(二)-基本操作
html5标签video(播放器)学习笔记(二)-基本操作 subying 发布时间: 2014/12/01 23:59 阅读: 13008 收藏: 21 点赞: 3 评论: 0 摘要 本文介绍了ht ...
- Kettle学习笔记(二)— 基本操作
目录 Kettle学习笔记(一)- 环境部署及运行 Kettle学习笔记(二)- 基本操作 kettle学习笔记(三)- 定时任务的脚本执行 Kettle学习笔记(四)- 总结 打开Kettle 打开 ...
- [Golang学习笔记] 08 链表
链表(Linked list)是一种常见数据结构,但并不会按线性的顺序存储数据,而是在每一个节点里存到下一个节点的指针. 由于不必须按顺序存储,链表在插入的时候可以达到O(1),比顺序表快得多,但是查 ...
- CUBRID学习笔记 48查询优化
cubrid的中sql查询语法 查询优化 c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com ...
- [原创]java WEB学习笔记48:其他的Servlet 监听器:域对象中属性的变更的事件监听器 (3 个),感知 Session 绑定的事件监听器(2个)
本博客为原创:综合 尚硅谷(http://www.atguigu.com)的系统教程(深表感谢)和 网络上的现有资源(博客,文档,图书等),资源的出处我会标明 本博客的目的:①总结自己的学习过程,相当 ...
- c++学习笔记—单链表基本操作的实现
用c++语言实现的单链表基本操作,包括单链表的创建(包括头插法和尾插法建表).结点的查找.删除.排序.打印输出.逆置.链表销毁等基本操作. IDE:vs2013 具体实现代码如下: #include ...
- linux C学习笔记03--单链表
单链表一直是程序员的基础,我也来复习下,下面是link.c中的代码,供main.c 调用,代码很简单,单链表的插入,删除,查找和遍历输出, #include <stdio.h> #incl ...
- 学习笔记 C++ 链表
今天查了不少关于链表的资料大概理解了链表,为记录只用留笔于此. 链表概述:动态的数据存储单元,可以比数组更加灵活. 链表的组成:存储的数据,下一个节点. 首先让我们用代码完成一个节点. class N ...
- 3ds max学习笔记(六)-- 基本操作(建模前奏)
1.界面设置 在3ds Max的版本的界面中,默认是较深.若需要切换至较亮的界面,步骤: 执行“自定义”菜单,选择“加载自定义用户界面方案”从弹出的界面中选择样式文件,单击“打开”即可: 注:“amg ...
随机推荐
- python 通用装饰器,带有参数的装饰器,
# 使用装饰器对有返回值的函数进行装饰# def func(functionName): # print('---func-1----') # def func_in(): # print(" ...
- Sqlserver2014 Master....提示异常,IIS未安装
Q:使用Windos认证,登录失败,问题待解决补充 Q:打开Sqlserver2014 Master....提示异常,IIS未安装 解决方案: 安装iis配置,并全部勾选asp.net特性等 Tip ...
- Asp.net MVC - 使用PRG模式(附源码)
阅读目录: 一. 传统的Asp.net页面问题 二.Asp.net MVC中也存在同样的问题 三.使用PRG模式 四.PRG模式在MVC上的实现 一. 传统的Asp.net页面问题 一个传统的Asp. ...
- 一起学Hadoop——使用自定义Partition实现hadoop部分排序
排序在很多业务场景都要用到,今天本文介绍如何借助于自定义Partition类实现hadoop部分排序.本文还是使用java和python实现排序代码. 1.部分排序. 部分排序就是在每个文件中都是有序 ...
- Flink--time-window 的高级用法
1.现实世界中的时间是不一致的,在 flink 中被划分为事件时间,提取时间,处理时间三种. 2.如果以 EventTime 为基准来定义时间窗口那将形成 EventTimeWindow,要求消息本身 ...
- Flink的广播变量
Flink支持广播变量,就是将数据广播到具体的taskmanager上,数据存储在内存中,这样可以减缓大量的shuffle操作: 比如在数据join阶段,不可避免的就是大量的shuffle操作,我们可 ...
- Python学习(十) —— 常用模块
一.collections模块 在内置数据类型(dict.list.set.tuple)的基础上,collections模块还提供了几个额外的数据类型:Counter.deque.defaultdic ...
- Linux LVM动态扩容
引用自: https://blog.csdn.net/u012439646/article/details/73380197 xfs_growfs /dev/centos/root 一.首先安 ...
- Codeforces 980F Cactus to Tree 仙人掌 Tarjan 树形dp 单调队列
原文链接https://www.cnblogs.com/zhouzhendong/p/CF980F.html 题目传送门 - CF980F 题意 给定一个 $n$ 个节点 $m$ 条长为 $1$ 的边 ...
- netty02(接受消息以后进行返回)
到这里接着上一篇netty01开始,没看过的可以点进去看一下再来 首先来说一下 ByteBuf 这个类吧,这个类是netty里面提供的,接受信息和返回信息格式都是它: ByteBuf 是一个抽 ...