自己写的c++双向链表

尝试使用lambda和模板写一个链表

#include "stdafx.h"
template<class T>
struct Node{
	T Value;
	struct Node * pNext;
	struct Node * pPrev;
};
template<class T>
class List{
private:
	Node<T> * m_pHead;
	int m_len;
	Node<T>* List<T>::NewNode(Node<T>* prev, T value);
	Node<T>* List<T>::DeleteNode(Node<T>* node, std::function<void(T)> pAction);
	void List<T>::MoveNext(Node<T>* last, std::function<Node<T>*(Node<T>*)> pAction);
	Node<T>* List<T>::MoveTo(T value);
	Node<T>* List<T>::MoveToAt(int index);
public:
	List();
	~List();
	int GetLength();
	bool isEmpty();
	bool Insert(T value);
	bool Remove(T value, std::function<void(T)> pAction);
	bool RemoveAt(int index, std::function<void(T)> pAction);
	T ElementAt(int index);
	void Dispose(std::function<void(T)> pAction);
	void Dispose();
	void ActionAsc(std::function<void(T)> pAction);
	void ActionDesc(std::function<void(T)> pAction);
};
#include "stdafx.h"
#include "List.h"
template<class T>
List<T>::List()
{
	this->m_len = 0;
	this->m_pHead = NULL;
}
template<class T>
List<T>::~List()
{
	if (this->m_len > 0)
	{
		this->Dispose();
	}
}
template<class T>
Node<T>* List<T>::NewNode(Node<T>* prev, T value)
{
	Node<T>* temp = new Node<T>();
	temp->pNext = NULL;
	temp->pPrev = prev;
	temp->Value = value;
	return temp;
};
template<class T>
Node<T>* List<T>::DeleteNode(Node<T>* node, std::function<void(T)> pAction)
{
	bool headFlag = node == m_pHead;
	Node<T>* result = NULL;
	T tempValue = node->Value;
	node->Value = NULL;
	if (pAction != NULL)
		pAction(tempValue);
	if (this->m_len != 1)
	{
		Node<T>* prev = node->pPrev;
		Node<T>* next = node->pNext;
		prev->pNext = next;
		next->pPrev = prev;
		result = node->pNext;
	}
	delete node;
	this->m_len--;
	if (headFlag)
	{
		m_pHead = result;
	}
	return result;
}
template<class T>
Node<T>* List<T>::MoveTo(T value)
{
	if (m_pHead == NULL)
		return NULL;
	Node<T>*p = m_pHead;
	do
	{
		if (p->Value == value)
		{
			return p;
		}
		else{
			p = p->pNext;
		}
	} while (p == NULL ? false : p != this->m_pHead);
	return NULL;
}
template<class T>
Node<T>* List<T>::MoveToAt(int index)
{
	if (m_pHead == NULL &&this->m_len <= index)
		return NULL;
	Node<T>*p = m_pHead;
	int tempIndex = -1;
	do
	{
		tempIndex++;
		if (index == tempIndex)
		{
			return p;
		}
		else{
			p = p->pNext;
		}
	} while (p == NULL ? false : p != this->m_pHead);
	return NULL;
}
template<class T>
void List<T>::MoveNext(Node<T>* last,std::function<Node<T>*(Node<T>*)> pAction)
{
	if (last == NULL || pAction == NULL)
		return;
	Node<T>*p = last;
	do
	{
		p = pAction(p);
	} while (p == NULL ? false : p != last);
}
template<class T>
int List<T>::GetLength()
{
	return this->m_len;
};
template<class T>
bool List<T>::isEmpty()
{
	return this->GetLength() == 0;
};
template<class T>
bool List<T>::Insert(T value)
{
	Node<T> * temp = this->NewNode(NULL, value);
	if (this->m_pHead == NULL)//head is empty
	{
		temp->pPrev = temp;
		this->m_pHead = temp;
	}
	else
	{
		Node<T> * p = this->m_pHead;
		p = p->pPrev;
		p->pNext = temp;
		temp->pPrev = p;
		this->m_pHead->pPrev = temp;
	}
	temp->pNext = m_pHead;
	this->m_len++;
	return true;
};
template<class T>
bool List<T>::Remove(T value, std::function<void(T)> pAction)
{
	Node<T>*p = this->MoveTo(value);
	if (p != NULL)
	{
		this->DeleteNode(p, pAction);
	}
	return p != NULL;
};
template<class T>
bool List<T>::RemoveAt(int index, std::function<void(T)> pAction)
{
	Node<T>*p = this->MoveToAt(index);
	if (p != NULL)
	{
		this->DeleteNode(p, pAction);
	}
	return p != NULL;
};
template<class T>
T List<T>::ElementAt(int index)
{
	Node<T>*p = this->MoveToAt(value);
	return p != NULL?p->Value:NULL;
};
template<class T>
void List<T>::Dispose(std::function<void(T)> pAction)
{
	this->MoveNext(this->m_pHead, [=](Node<T>* p){return this->DeleteNode(p, pAction); });
};
template<class T>
void List<T>::Dispose()
{
	this->Dispose([](T t){});
}
template<class T>
void List<T>::ActionAsc(std::function<void(T)> pAction)
{
	this->MoveNext(this->m_pHead,[=](Node<T>* p){pAction(p->Value); return p->pNext; });
};
template<class T>
void List<T>::ActionDesc(std::function<void(T)> pAction)
{
	this->MoveNext(this->m_pHead->pPrev, [=](Node<T>* p){pAction(p->Value); return p->pPrev; });
};

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 14:59:37

自己写的c++双向链表的相关文章

自己写的一个双向链表容器

1 package com.lovo; 2 3 public class SuperLinkedList <T>{ 4 private int size; 5 private SuperLinkedListNode<T> firstNode; 6 private SuperLinkedListNode<T> lastNode; 7 /** 8 * 添加元素(添加在链表的末尾) 9 * @param o 10 */ 11 public void add(T o) { 12

string双向链表

写一个string双向链表模块,具有提取和插入功能.通过建立一个程序语言种类的表来练习这个模块.为这个表提供一个sort()函数.并提供一个函数反转表中字符串的顺序. 环境:vs2005 win32控制台程序 #include <iostream> #include <assert.h> #include <string> #include <algorithm> // for std::swap using std::string; namespace S

[C++]C++的模板编程

我是搬运工,原文地址:http://www.cppblog.com/besterChen/archive/2010/07/22/121000.html 当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同而已. C++ 提供了“模板”这一特性, 可以将“类型” 参数化, 使得编写的代码更具有通用性. 因此大家都称模板编程为 “通用编程”或 “泛型编程

C++的模板编程

当我们越来越多的使用C++的特性, 将越来越多的问题和事物抽象成对象时, 我们不难发现:很多对象都具有共性. 比如 数值可以增加.减少:字符串也可以增加减少. 它们的动作是相似的, 只是对象的类型不同而已. C++ 提供了“模板”这一特性, 可以将“类型” 参数化, 使得编写的代码更具有通用性. 因此大家都称模板编程为 “通用编程”或 “泛型编程”. 一般而言, 模板分为 函数模板 和 类模板,下面就让我们分别来了解一下它们. 一. 函数模板 1. 函数模板的定义和使用 定义一个模板函数的格式并

一步一步写算法(之双向链表)

原文:一步一步写算法(之双向链表) [ 声明:版权所有,欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 前面的博客我们介绍了单向链表.那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针.双向链表相比较单向链表,主要有下面几个特点: (1)在数据结构中具有双向指针 (2)插入数据的时候需要考虑前后的方向的操作 (3)同样,删除数据的是有也需要考虑前后方向的操作 那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下: (

用Python写单向链表和双向链表

链表是一种数据结构,链表在循环遍历的时候效率不高,但是在插入和删除时优势比较大. 链表由一个个节点组成. 单向链表的节点分为两个部分:存储的对象和对下一个节点的引用.注意是指向下一个节点. 而双向链表区别于单向链表的是它是由三个部分组成:存储的对象.对下一个节点的引用.对上一个节点的引用,可以实现双向遍历. 单向列表的结构如下图: head是头节点,tail是尾节点,每个节点由Data存储对象和Next对下一个节点引用组成 下面说一下单向链表插入和删除的过程. 插入一个新节点: 原理:前一个节点

01-(2)数据结构- 一步一步写算法(之双向链表)

前面的博客我们介绍了单向链表.那么我们今天介绍的双向链表,顾名思义,就是数据本身具备了左边和右边的双向指针.双向链表相比较单向链表,主要有下面几个特点: (1)在数据结构中具有双向指针 (2)插入数据的时候需要考虑前后的方向的操作 (3)同样,删除数据的是有也需要考虑前后方向的操作 那么,一个非循环的双向链表操作应该是怎么样的呢?我们可以自己尝试一下: (1)定义双向链表的基本结构 [cpp] view plain copy typedef struct _DOUBLE_LINK_NODE {

看数据结构写代码(6)双向链表的实现

双向链表 只是 比 单链表 多了 一个 指向 前驱的 指针,在插入 和 删除 元素的 时候 得多处理一些.其余 没什么 区别. 而循环链表 的 尾指针 不再 指向 NULL,而是 指向 头指针,这样 既可以循环遍历,又节省 存储空间 . 每种链表 都有 好处,至于 如何 取舍,得看需求. 下面 奉上 双向链表的实现代码: // DoubleLinkList.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <stdlib.h

HashMap+双向链表手写LRU缓存算法/页面置换算法

import java.util.Hashtable; //https://zhuanlan.zhihu.com/p/34133067 class DLinkedList { String key; //键 int value; //值 DLinkedList pre; //双向链表前驱 DLinkedList next; //双向链表后继 } public class LRUCache { private Hashtable<String,DLinkedList> cache = new H