代码改变世界

双向(端)链表、栈、队列

2011-01-03 13:19  Clingingboy  阅读(1414)  评论(0编辑  收藏  举报

 

双端链表

 

双端栈

 

双端队列

从实用角度,感受不出双端队列的好处,但其可以充当栈和队列的角色.

参考资料:http://baike.baidu.com/view/1627726.htm

Test

static void Main()
{
    var deque = new Deque<int>();
    Console.WriteLine("Stack:");
    //stack
    deque.AddFirst(1);
    deque.AddFirst(2);
    deque.AddFirst(3);
    Console.WriteLine(deque.RemoveFirst());
    Console.WriteLine(deque.RemoveFirst());
    Console.WriteLine(deque.RemoveFirst());

    //queue
    Console.WriteLine("Queue:");
    deque.AddFirst(1);
    deque.AddFirst(2);
    deque.AddFirst(3);
    Console.WriteLine(deque.RemoveLast());
    Console.WriteLine(deque.RemoveLast());
    Console.WriteLine(deque.RemoveLast());  

}

image

当AddFirst和AddLast同时使用时则变成2个栈了

deque.AddFirst(1);
deque.AddFirst(2);
deque.AddFirst(3);
deque.AddLast(6);
deque.AddLast(7);
deque.AddLast(8);
Console.WriteLine(deque.RemoveLast());
Console.WriteLine(deque.RemoveLast());
Console.WriteLine(deque.RemoveLast());  
Console.WriteLine(deque.RemoveFirst());
Console.WriteLine(deque.RemoveFirst());
Console.WriteLine(deque.RemoveFirst());

image

简单实现

public interface IDeque<T>
{
    void AddFirst(T node);

    void AddLast(T node);

    T RemoveFirst();

    T RemoveLast();

    T PeekFirst();

    T PeekLast();
}

public class Deque<T> : IDeque<T>
{


    private T[] _elements;
    private int head, end;

    public Deque()
    {
        _elements = new T[2];
    }

    //1,2,3,4
    public Deque(int capacity)
    {
        _elements=new T[capacity];
    }

    public void AddFirst(T node)
    {
        //loop index
        if (--head < 0)
            head += _elements.Length;
        //val
        _elements[head] = node;
        //check capacity
        if (head == end)
            DoubleCapacity();
    }

    public void AddLast(T node)
    {
        _elements[end] = node;

        if (++end < 0)
            end -= _elements.Length;

        if (head == end)
            DoubleCapacity();
    }

    private void DoubleCapacity()
    {
        int p = head;
        int n = _elements.Length;
        int r = n - p; 
        int newCapacity = n << 1;

        T[] a = new T[newCapacity];

        Array.Copy(_elements, p, a, 0, r);
        Array.Copy(_elements, 0, a, r, p);
        _elements = (T[]) a;
        head = 0;
        end = n;
    }

    public T RemoveFirst()
    {
        
        T result = _elements[head]; 

        _elements[head] = default(T);     

        if (++head >= _elements.Length)
            head -= _elements.Length;

        return result;
    }

    public T RemoveLast()
    {
        if (--end < 0)
            end += _elements.Length;

        T result = _elements[end];
        _elements[end] = default(T);
        
        return result;
    }

    public T PeekFirst()
    {
        return _elements[head];
    }

    public T PeekLast()
    {
        if (end == 0)
            return _elements[_elements.Length - 1];
        else
            return _elements[end - 1];
    }

    public int GetLength()
    {
        return (end - head) & (_elements.Length - 1);
    }

    public bool IsEmpty()
    {
        return head == end;
    }

    public void Display()
    {
        foreach (var element in _elements)
        {
            Console.Write(element+",");
        }
        Console.WriteLine();
    }
}

优先级队列PriorityQueue

两个主要的方法,我想的与源码不同,结果是相同的,没掌握一定技巧,以后回头再看吧

/// <summary>
/// 上滤,小为上,升序
/// </summary> /// <param name="item">The item.</param> private void PercolateUpAscending(T item) { int i; for (i = Count - 1; i >= 0; i--) { if (Compare(_heap[i], item) > 0) { _heap[i + 1] = _heap[i]; } else break; } _heap[++i] = item; Count++; } /// <summary> /// 上滤,大为上,降序 /// </summary> /// <param name="item">The item.</param> private void PercolateUpDescending(T item) { int i; for (i = Count - 1; i >= 0; i--) { if (Compare(item, _heap[i]) > 0) { _heap[i + 1] = _heap[i]; } else break; } _heap[++i] = item; Count++; }