带头尾节点的双向链表

#include<iostream>
#include<assert.h>
using namespace std;
typedef int DataType;
//双向链表,无头节点
struct LinkNode
{
	//struct默认是公有访问限定符
public:
	LinkNode(const DataType& x)
		:_data(x)
		, _prev(NULL)
		, _next(NULL)
	{}
	~LinkNode()
	{

	}
public:
	DataType _data;
	LinkNode* _prev;
	LinkNode* _next;
};

class List
{
public:
	List()
		:_head(NULL)
		, _tail(NULL)
	{
	}
	~List()
	{

	}
	void PushBack(const DataType& x)
	{
		LinkNode* tmp = new LinkNode(x);

		if (NULL == _tail)
		{
			_head = _tail=tmp;
		}
		else
		{
			tmp->_prev = _tail;
			_tail->_next = tmp;
			_tail = _tail->_next;

		}
	}
	void  PopBack()
	{
		LinkNode* cur = _head;
		if (_tail == NULL)
		{
			return;
		}
		else	if (_head == _tail)
		{
			delete _head;
			_head = _tail = NULL;
		}
		else
		{
			LinkNode* del = _tail;
			_tail->_prev->_next = NULL;
			_tail = _tail->_prev;
			delete del;
		}
	}
	void PushFront(const DataType& x)
	{
		LinkNode* tmp = new LinkNode(x);
		//如果没有节点
		if (NULL== _tail)
		{
			_tail=_head = tmp;
		}
		else 
		{
			tmp->_next = _head;
			_head->_prev = tmp;

			_head = tmp;

		}

	}
	void PopFront()
	{
		if (_head == NULL)
			return;
		else if (_head==_tail)
		{
			free(_head);
			_head = _tail=NULL;
		}
		else
		{
			LinkNode* del = _head;
			_head = _head->_next;
			_head->_prev = NULL;

			delete del;
		}
	}
	LinkNode* Find(const DataType& x)
	{
		LinkNode* cur = _head;
		while (cur)
		{
			if (cur->_data == x)
				return cur;
			cur = cur->_next;
		}
		return NULL;
	}
	void Erase(LinkNode* pos)
	{
		assert(pos);
		//处理pos是头,尾或头和尾
		LinkNode* del = NULL;
		if (pos == _head)
		{
			del = pos;
			_head = _head->_next;
			_head->_prev = NULL;
		}
		if (pos==_tail)
		{
			del = pos;
			_tail = _tail->_prev;
			_tail->_next = NULL;
		}
		if (del == NULL)
		{
			LinkNode* prev = pos->_prev;
			LinkNode* next = pos->_next;
			prev->_next = next;
			next->_prev = prev;
		}
		delete del;
	}
	void Insert(LinkNode* pos, const DataType& x)
	{
		assert(pos);
		LinkNode* tmp = new LinkNode(x);
		if (pos == _tail)
		{
			_tail->_next = tmp;
			tmp->_prev = _tail;
			_tail = tmp;
		}
		else
		{
			LinkNode* next = pos->_next;
			tmp->_next = next;
			next->_prev = tmp;

			pos->_next = tmp;
			tmp->_prev = pos;
		}
	}
	void  DisPlay()
	{
		LinkNode* cur = _head;
		while (cur)
		{
			cout << (cur->_data) << "->";
			cur = cur->_next;
		}
		cout << "NULL" << endl;
	}
private:
	LinkNode* _head;
	LinkNode* _tail;
};
void Test1()
{
	List l1;
	l1.PushBack(1);
	l1.PushBack(2);
	l1.PushBack(3);
	l1.PushBack(4);
	l1.PushBack(5);
	l1.PushBack(6);
	l1.DisPlay();

	l1.PopBack();
	l1.DisPlay();

	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.PopBack();
	l1.DisPlay();

}
void Test2()
{
	List l2;
	l2.PushFront(1);
	l2.PushFront(2);
	l2.PushFront(3);
	l2.PushFront(4);
	l2.PushFront(5);
	l2.PushFront(6);
	l2.DisPlay();

	l2.PopFront();
	l2.PopFront();
	l2.PopFront();
	l2.PopFront();
	l2.DisPlay();
	l2.PopFront();
	l2.PopFront();
	l2.PopFront();
	l2.PopFront();
	l2.DisPlay();
}
void Test3()
{
	List l2;
	l2.PushFront(1);
	l2.PushFront(2);
	l2.PushFront(3);
	l2.PushFront(4);
	l2.PushFront(5);
	l2.PushFront(6);
	l2.DisPlay();

	LinkNode* ret = l2.Find(6);
	//l2.Erase(ret);

	l2.Insert(ret, 7);
	l2.DisPlay();
}
int main()
{
	Test3();
	system("pause");
	return 0;
}
时间: 2024-08-06 01:07:42

带头尾节点的双向链表的相关文章

算法导论之九(10.2不带哨兵节点和带哨兵节点的双向链表)

不带哨兵节点的双向链表即一般的双向链表,有一个头指针指向第一个节点,每个节点有key值和两个指针next和pre,分别指向前后相邻的节点,头结点的pre=NULL,尾节点的next=NULL,比较明了,但是也有麻烦的地方:在做查找删除节点等操作的时候,免不了要判断边界条件,比如node==NULL等.先来看看这种链表的代码: /* * 实现没有哨兵节点的双向链表,需要自己判断边界条件 */ #include <iostream> using namespace std; class list

带头尾节点的双向循环链表

注意测试用例的选取!! #include<iostream> using namespace std; #include<string> template<class T> struct LinkNode { LinkNode(const T& x) :_data(x) , _prev(NULL) , _next(NULL) { } T _data; LinkNode<T>* _prev; LinkNode<T>* _next; }; t

C++二叉搜索树(带父亲节点,2种节点删除方法的比较.)

这里写代码片#include <iostream> #include <iomanip> using namespace std; template<typename Type> class BSTNode { public: Type data; BSTNode<Type> *left; BSTNode<Type> *right; BSTNode<Type> *parent;//带父亲节点的搜索二叉树. BSTNode(Type d

使用带有头尾节点的单链表实现队列

package db; public class Queue<E> { /** * 内部类--单链表 * @author fightzhao * * @param <E> */ private static class Node<E> { public Node<E> next; public E data; public Node(E data, Node<E> next) { this.data = data; this.next = nex

双向链表(未完)

双向链表-未测试(一口气写完,错很多) #ifndef VLYFLIST_H_ #define VLYFLIST_H_ namespace vlyflist { //带头尾节点的双向链表 template <typename T> class VlyfList { public: friend class Iterator; //双向节点 struct Node { Node(T& x) : data(x), prev(nullptr), next(nullptr) {} T data

深入解读synchronized和ReentrantLock

故事起源于上次阿里电面的3个问题.问题1,jvm中线程分为哪些状态.问题2,在执行Thread.start()方法后,线程是不是马上运行.问题3,java中的synchronized和ReentrantLock有什么不同.当时我的回答不是很好,就不说了,面试之后,在网上搜了很多文章,对照着jdk源码(1.8),发现这3个问题存在着一些联系,接下来,就从这3个问题入手,仔细解读一下线程,synchronized和ReentrantLock. 问题1 jvm中的线程分为哪些状态 这个可以看一下jdk

【Java集合】-- LinkedList源码解析

目录 继承体系 数据结构 源码解析 1.属性 2.构造方法 LinkedList() LinkedList(Collection<? extends E> c) 3.添加元素 add(E e) addFirst(E e) addLast(E e) add(int index, E element) offer(E e) offerFirst(E e) offerLast(E e) 总结 4.获取元素 get(int index) getFirst() getLast() peek() 5.删除

【算法导论】红黑树详解之一(插入)

本文地址:http://blog.csdn.net/cyp331203/article/details/42677833 作者:苦_咖啡 欢迎转载,但转载请注明出处,否则将追究相应责任,谢谢!. 红黑树是建立在二叉查找树的基础之上的,关于二叉查找树可以参看[算法导论]二叉搜索树的插入和删除和[算法导论]二叉树的前中后序非递归遍历实现.对于高度为h的二叉查找树而言,它的SEARCH.INSERT.DELETE.MINIMUM.MAXIMUM等操作的时间复杂度均为O(h).所以在二叉查找树的高度较高

java之高并发与多线程

进程和线程的区别和联系 从资源占用,切换效率,通信方式等方面解答 线程具有许多传统进程所具有的特征,故又称为轻型进程(Light—Weight Process)或进程元:而把传统的进程称为重型进程(Heavy—Weight Process),它相当于只有一个线程的任务.在引入了线程的操作系统中,通常一个进程都有若干个线程,至少需要一个线程.下面,我们从调度.并发性. 系统开销.拥有资源等方面,来比较线程与进程. 1.调度 在传统的操作系统中,拥有资源的基本单位和独立调度.分派的基本单位都是进程.