实现一个基于双向链表的双端队列

package day1_30_5_2;

public class DoubleLinkedList {

	private Link first;
	private Link last;

	public DoubleLinkedList(){
		first = null;
		last = null;
	}

	//判断是不是为空
	public boolean isEmpty(){
		return first == null;
	}

	//在双向链表的前端插入
	public void insertFirst(long dd){
		Link newLink = new Link(dd);
		if(isEmpty()){//如果双向链表为空,就让last指针直接指向新创建的节点
			last = newLink;
		}else
			first.previous = newLink;
		    newLink.next = first;
		    first = newLink;

	}

	//在双向链表的后端插入
	public void insertLast(long dd){
		Link newLink = new Link(dd);
		if(isEmpty()){
			first = newLink;
		}else{
			last.next = newLink;
			newLink.previous = last;

		}
		last = newLink;

	}

	//删除第一个节点的实现
	public Link deleteFirst(){

		Link temp = first;
		if(first.next == null){//如果只有一个元素
			last = null;
		}
		else
			first.next.previous = null;
		    first = first.next;
		    return temp;

	}

	//删除最后一个节点的实现
	public Link deleteLast(){
		Link temp = last;
		if (first.next == null) // if only one item
            first = null; // first --> null
        else
            last.previous.next = null; // old previous --> null
        last = last.previous; // old previous <-- last
        return temp;
	}

	//在某个元素的后面添加一个元素,insert dd after key
	public boolean insertAfter(long key,long dd){
		Link current = first;

		while(current.dData != key){
			current = current.next;
			if(current == null){
				return false;
			}
		}
		//创建一个新的节点
		Link newLink = new Link(dd);
		//current  在last
		if(current == last){
			newLink.next = null;
			last = newLink;
		}else{//不是最后一个节点
			newLink.next = current.next;
			current.next.previous = newLink;

		}

		newLink.previous = current;
		current.next = newLink;
		return true;
	}

	public Link deleteKey(long key){

		 Link current = first; // start at beginning
	        while (current.dData != key) // until match is found,
	        {
	            current = current.next; // move to next link
	            if (current == null)
	                return null; // didn‘t find it
	        }
	        if (current == first) // found it; first item?
	            first = current.next; // first --> old next
	        else
	            // not first
	            // old previous --> old next
	            current.previous.next = current.next;  

	        if (current == last) // last item?
	            last = current.previous; // old previous <-- last
	        else
	            // not last
	            // old previous <-- old next
	            current.next.previous = current.previous;
	        return current; // return value  

	}

	public void displayForward() {
        System.out.print("List (first-->last): ");
        Link current = first; // start at beginning
        while (current != null) // until end of list,
        {
            current.displayLink(); // display data
            current = current.next; // move to next link
        }
        System.out.println("");
    }  

    // -------------------------------------------------------------
    public void displayBackward() {
        System.out.print("List (last-->first): ");
        Link current = last; // start at end
        while (current != null) // until start of list,
        {
            current.displayLink(); // display data
            current = current.previous; // move to previous link
        }
        System.out.println("");
    }  

}

  

时间: 2024-08-07 01:44:52

实现一个基于双向链表的双端队列的相关文章

Deque 双端队列

Deque允许在队列的头部或尾部进行出队和入队操作 LinkedBlockingDeque是一个线程安全的双端队列实现,可以说他是最为复杂的一种队列,在内部实现维护了前端和后端节点,但是其没有实现读写分离,因此同一时间只能有一个线程对其进行操作.在高并发中性能要远低于其他BlockingQueue.更要低于ConcurrentLinkedQueue,在jdk早期有一个非线程安全的Deque就是ArrayDeque了,java6里添加了LinkedBlockingDeque来弥补多线程场景下线程安

关于双端队列 deque 模板 &amp;&amp; 滑动窗口 (自出)

嗯... deque 即为双端队列,是c++语言中STL库中提供的一个东西,其功能比队列更强大,可以从队列的头与尾进行操作... 但是它的操作与队列十分相似,详见代码1: 1 #include <cstdio> 2 #include <iostream> 3 #include <deque> 4 //实际上,引用queue头文件也可以,里面包含了deque头文件 5 6 using namespace std; 7 8 deque<int> dq; //定义

双端队列篇deque SDUT OJ 双向队列

双向队列 Time Limit: 1000MS Memory limit: 65536K 题目描述 想想双向链表……双向队列的定义差不多,也就是说一个队列的队尾同时也是队首:两头都可以做出队,入队的操作. 现在给你一系列的操作,请输出最后队列的状态: 命令格式: LIN X  X表示一个整数,命令代表左边进队操作: RIN X  表示右边进队操作: ROUT LOUT   表示出队操作: 输入 第一行包含一个整数M(M<=10000),表示有M个操作: 以下M行每行包含一条命令: 命令可能不合法

std::deque双端队列介绍

在建立vector容器时,一般来说伴随这建立空间->填充数据->重建更大空间->复制原空间数据->删除原空间->添加新数据,如此反复,保证vector始终是一块独立的连续内存空间:在建立deque容器时,一般便随着建立空间->建立数据->建立新空间->填充新数据,如此反复,没有原空间数据的复制和删除过程,是由多个连续的内存空间组成的. C++ STL容器deque和vector很类似,也是采用动态数组来管理元素. 与vector不同的是deque的动态数组首

《算法实战策略》-chaper19-队列、栈和双端队列

对于计算机专业的学生来说,他们一定会很熟悉一句话:程序设计 = 算法 + 数据结构.而根据笔者的理解,所谓程序设计其实就是为了编程解决实际问题,所谓算法是一种解决问题某种思维的方法,但是思维需要得到编程实践,这就需要基于数据结构.一个好的数据结构能够让我们更快更高效得处理数据,有些模拟性.数学背景并不深厚的的问题,仅仅基于高效的数据结构就可以解决.那么这一章节,我们就单独将队列.栈.双端队列拿出来,结合具体的题目,看看它们是如何灵活的运用到解题策略当中的. 考虑到笔者在<入门经典>和<啊

设计循环队列——写起来最清爽的还使用原生的deque 双端队列

622. 设计循环队列 难度中等89收藏分享切换为英文关注反馈 设计你的循环队列实现. 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环.它也被称为“环形缓冲器”. 循环队列的一个好处是我们可以利用这个队列之前用过的空间.在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间.但是使用循环队列,我们能使用这些空间去存储新的值. 你的实现应该支持如下操作: MyCircularQueue(k): 构造器,设置队

8、泛型程序设计与c++标准模板库2.3双端队列容器

双端队列容器是一种放松了访问权限的队列.除了从队列的首部和尾部访问元素外,标准的双端队列也支持通过使用下标操作符"[]"进行直接访问. 它提供了直接访问和顺序访问方法.其头文件为<deque>. 1)双端队列容器的构造函数 有4中形式的构造函数: deque();//构造size()为0的双端队列容器 deque(size_type n,const T& v=T());//初始化大小为n的双端队列,第二个参数是每个元素的初始值,默认为T()构造的对象 deque(c

nyoj1117 鸡蛋队列 (双端队列,deque)

题目1117 题目信息 运行结果 本题排行 讨论区 鸡蛋队列 时间限制:1000 ms  |  内存限制:65535 KB 难度:1 描述 将两根筷子平行的放在一起,就构成了一个队列.将带有编号的鸡蛋放到两根筷子之间叫做入队(push),将筷子之间的鸡蛋拿出来叫做出队(pop).但这两种方式有特殊的定义,对于入队,只能将鸡蛋从队列的尾部向里放入:对于出队,只能将鸡蛋从队列的头部向外将鸡蛋拿出来. 将①.②入队: 头____________尾                         ___

算法导论之八(10.1-5单数组实现双端队列)

算法导论第三版P131 题目: 10.1-5 栈插入和删除元素只能在同一端进行,队列的插入操作和删除操作分别在两端进行,与它们不同的,有一种双端队列(deque),其插入和删除操作都可以在两端进行.写出4个时间均为O(1)的过程,分别实现在双端队列插入和删除元素的操作,该队列使用一个数组实现的. 注意点: 1.左右端点指向的位置是类似于队列中的tail端点,是下一个插入操作的位置. 2.然后注意遍历的时候,左端点和右端点的位置关系,有两种可能,所以遍历的方式不一样. 代码: /* * 使用单数组