mirror of
				https://github.com/krahets/hello-algo.git
				synced 2025-11-04 14:18:20 +08:00 
			
		
		
		
	feature: Add csharp code array_deque and linkedlist_deque (#405)
* feature: Add csharp code array_deque and linkedlist_deque * fix code style issue in comments
This commit is contained in:
		
							
								
								
									
										175
									
								
								codes/csharp/chapter_stack_and_queue/array_deque.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								codes/csharp/chapter_stack_and_queue/array_deque.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,175 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: array_deque.cs
 | 
			
		||||
 * Created Time: 2023-03-08
 | 
			
		||||
 * Author: hpstory (hpstory1024@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
 | 
			
		||||
namespace hello_algo.chapter_stack_and_queue
 | 
			
		||||
{
 | 
			
		||||
    /* 基于环形数组实现的双向队列 */
 | 
			
		||||
    public class ArrayDeque
 | 
			
		||||
    {
 | 
			
		||||
        private readonly int[] nums;  // 用于存储双向队列元素的数组
 | 
			
		||||
        private int front;   // 队首指针,指向队首元素
 | 
			
		||||
        private int queSize; // 双向队列长度
 | 
			
		||||
 | 
			
		||||
        /* 构造方法 */
 | 
			
		||||
        public ArrayDeque(int capacity)
 | 
			
		||||
        {
 | 
			
		||||
            this.nums = new int[capacity];
 | 
			
		||||
            front = queSize = 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 获取双向队列的容量 */
 | 
			
		||||
        public int capacity()
 | 
			
		||||
        {
 | 
			
		||||
            return nums.Length;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 获取双向队列的长度 */
 | 
			
		||||
        public int size()
 | 
			
		||||
        {
 | 
			
		||||
            return queSize;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 判断双向队列是否为空 */
 | 
			
		||||
        public bool isEmpty()
 | 
			
		||||
        {
 | 
			
		||||
            return queSize == 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 计算环形数组索引 */
 | 
			
		||||
        private int index(int i)
 | 
			
		||||
        {
 | 
			
		||||
            // 通过取余操作实现数组首尾相连
 | 
			
		||||
            // 当 i 越过数组尾部后,回到头部
 | 
			
		||||
            // 当 i 越过数组头部后,回到尾部
 | 
			
		||||
            return (i + capacity()) % capacity();
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队首入队 */
 | 
			
		||||
        public void pushFirst(int num)
 | 
			
		||||
        {
 | 
			
		||||
            if (queSize == capacity())
 | 
			
		||||
            {
 | 
			
		||||
                Console.WriteLine("双向队列已满");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // 队首指针向左移动一位
 | 
			
		||||
            // 通过取余操作,实现 front 越过数组头部后回到尾部
 | 
			
		||||
            front = index(front - 1);
 | 
			
		||||
            // 将 num 添加至队首
 | 
			
		||||
            nums[front] = num;
 | 
			
		||||
            queSize++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队尾入队 */
 | 
			
		||||
        public void pushLast(int num)
 | 
			
		||||
        {
 | 
			
		||||
            if (queSize == capacity())
 | 
			
		||||
            {
 | 
			
		||||
                Console.WriteLine("双向队列已满");
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
            // 计算尾指针,指向队尾索引 + 1
 | 
			
		||||
            int rear = index(front + queSize);
 | 
			
		||||
            // 将 num 添加至队尾
 | 
			
		||||
            nums[rear] = num;
 | 
			
		||||
            queSize++;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队首出队 */
 | 
			
		||||
        public int pollFirst()
 | 
			
		||||
        {
 | 
			
		||||
            int num = peekFirst();
 | 
			
		||||
            // 队首指针向后移动一位
 | 
			
		||||
            front = index(front + 1);
 | 
			
		||||
            queSize--;
 | 
			
		||||
            return num;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队尾出队 */
 | 
			
		||||
        public int pollLast()
 | 
			
		||||
        {
 | 
			
		||||
            int num = peekLast();
 | 
			
		||||
            queSize--;
 | 
			
		||||
            return num;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 访问队首元素 */
 | 
			
		||||
        public int peekFirst()
 | 
			
		||||
        {
 | 
			
		||||
            if (isEmpty())
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException();
 | 
			
		||||
            }              
 | 
			
		||||
            return nums[front];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 访问队尾元素 */
 | 
			
		||||
        public int peekLast()
 | 
			
		||||
        {
 | 
			
		||||
            if (isEmpty())
 | 
			
		||||
            {
 | 
			
		||||
                throw new InvalidOperationException();
 | 
			
		||||
            }               
 | 
			
		||||
            // 计算尾元素索引
 | 
			
		||||
            int last = index(front + queSize - 1);
 | 
			
		||||
            return nums[last];
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 返回数组用于打印 */
 | 
			
		||||
        public int[] toArray()
 | 
			
		||||
        {
 | 
			
		||||
            // 仅转换有效长度范围内的列表元素
 | 
			
		||||
            int[] res = new int[queSize];
 | 
			
		||||
            for (int i = 0, j = front; i < queSize; i++, j++)
 | 
			
		||||
            {
 | 
			
		||||
                res[i] = nums[index(j)];
 | 
			
		||||
            }
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class array_deque
 | 
			
		||||
    {
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test()
 | 
			
		||||
        {
 | 
			
		||||
            /* 初始化双向队列 */
 | 
			
		||||
            ArrayDeque deque = new ArrayDeque(10);
 | 
			
		||||
            deque.pushLast(3);
 | 
			
		||||
            deque.pushLast(2);
 | 
			
		||||
            deque.pushLast(5);
 | 
			
		||||
            Console.WriteLine("双向队列 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 访问元素 */
 | 
			
		||||
            int peekFirst = deque.peekFirst();
 | 
			
		||||
            Console.WriteLine("队首元素 peekFirst = " + peekFirst);
 | 
			
		||||
            int peekLast = deque.peekLast();
 | 
			
		||||
            Console.WriteLine("队尾元素 peekLast = " + peekLast);
 | 
			
		||||
 | 
			
		||||
            /* 元素入队 */
 | 
			
		||||
            deque.pushLast(4);
 | 
			
		||||
            Console.WriteLine("元素 4 队尾入队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
            deque.pushFirst(1);
 | 
			
		||||
            Console.WriteLine("元素 1 队首入队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 元素出队 */
 | 
			
		||||
            int pollLast = deque.pollLast();
 | 
			
		||||
            Console.WriteLine("队尾出队元素 = " + pollLast + ",队尾出队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
            int pollFirst = deque.pollFirst();
 | 
			
		||||
            Console.WriteLine("队首出队元素 = " + pollFirst + ",队首出队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 获取双向队列的长度 */
 | 
			
		||||
            int size = deque.size();
 | 
			
		||||
            Console.WriteLine("双向队列长度 size = " + size);
 | 
			
		||||
 | 
			
		||||
            /* 判断双向队列是否为空 */
 | 
			
		||||
            bool isEmpty = deque.isEmpty();
 | 
			
		||||
            Console.WriteLine("双向队列是否为空 = " + isEmpty);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										213
									
								
								codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										213
									
								
								codes/csharp/chapter_stack_and_queue/linkedlist_deque.cs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,213 @@
 | 
			
		||||
/**
 | 
			
		||||
 * File: linkedlist_deque.cs
 | 
			
		||||
 * Created Time: 2023-03-08
 | 
			
		||||
 * Author: hpstory (hpstory1024@163.com)
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
using NUnit.Framework;
 | 
			
		||||
 | 
			
		||||
namespace hello_algo.chapter_stack_and_queue
 | 
			
		||||
{
 | 
			
		||||
    /* 双向链表结点 */
 | 
			
		||||
    public class ListNode
 | 
			
		||||
    {
 | 
			
		||||
        public int val;       // 结点值
 | 
			
		||||
        public ListNode? next; // 后继结点引用(指针)
 | 
			
		||||
        public ListNode? prev; // 前驱结点引用(指针)
 | 
			
		||||
 | 
			
		||||
        public ListNode(int val)
 | 
			
		||||
        {
 | 
			
		||||
            this.val = val;
 | 
			
		||||
            prev = null;
 | 
			
		||||
            next = null;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* 基于双向链表实现的双向队列 */
 | 
			
		||||
    public class LinkedListDeque
 | 
			
		||||
    {
 | 
			
		||||
        private ListNode? front, rear; // 头结点 front, 尾结点 rear
 | 
			
		||||
        private int queSize = 0;      // 双向队列的长度
 | 
			
		||||
 | 
			
		||||
        public LinkedListDeque()
 | 
			
		||||
        {
 | 
			
		||||
            front = null;
 | 
			
		||||
            rear = null;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 获取双向队列的长度 */
 | 
			
		||||
        public int size()
 | 
			
		||||
        {
 | 
			
		||||
            return queSize;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 判断双向队列是否为空 */
 | 
			
		||||
        public bool isEmpty()
 | 
			
		||||
        {
 | 
			
		||||
            return size() == 0;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 入队操作 */
 | 
			
		||||
        private void push(int num, bool isFront)
 | 
			
		||||
        {
 | 
			
		||||
            ListNode node = new ListNode(num);
 | 
			
		||||
            // 若链表为空,则令 front, rear 都指向 node
 | 
			
		||||
            if (isEmpty())
 | 
			
		||||
            {
 | 
			
		||||
                front = node;
 | 
			
		||||
                rear = node;
 | 
			
		||||
            }
 | 
			
		||||
            // 队首入队操作
 | 
			
		||||
            else if (isFront)
 | 
			
		||||
            {
 | 
			
		||||
                // 将 node 添加至链表头部
 | 
			
		||||
                front.prev = node;
 | 
			
		||||
                node.next = front;
 | 
			
		||||
                front = node; // 更新头结点                           
 | 
			
		||||
            }
 | 
			
		||||
            // 队尾入队操作
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                // 将 node 添加至链表尾部
 | 
			
		||||
                rear.next = node;
 | 
			
		||||
                node.prev = rear;
 | 
			
		||||
                rear = node;  // 更新尾结点
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            queSize++; // 更新队列长度
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队首入队 */
 | 
			
		||||
        public void pushFirst(int num)
 | 
			
		||||
        {
 | 
			
		||||
            push(num, true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队尾入队 */
 | 
			
		||||
        public void pushLast(int num)
 | 
			
		||||
        {
 | 
			
		||||
            push(num, false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 出队操作 */
 | 
			
		||||
        private int? poll(bool isFront)
 | 
			
		||||
        {
 | 
			
		||||
            // 若队列为空,直接返回 null
 | 
			
		||||
            if (isEmpty())
 | 
			
		||||
            {
 | 
			
		||||
                return null;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            int val;
 | 
			
		||||
            // 队首出队操作
 | 
			
		||||
            if (isFront)
 | 
			
		||||
            {
 | 
			
		||||
                val = front.val; // 暂存头结点值
 | 
			
		||||
                                 // 删除头结点
 | 
			
		||||
                ListNode fNext = front.next;
 | 
			
		||||
                if (fNext != null)
 | 
			
		||||
                {
 | 
			
		||||
                    fNext.prev = null;
 | 
			
		||||
                    front.next = null;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                front = fNext;   // 更新头结点
 | 
			
		||||
            }
 | 
			
		||||
            // 队尾出队操作
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                val = rear.val;  // 暂存尾结点值
 | 
			
		||||
                                 // 删除尾结点
 | 
			
		||||
                ListNode rPrev = rear.prev;
 | 
			
		||||
                if (rPrev != null)
 | 
			
		||||
                {
 | 
			
		||||
                    rPrev.next = null;
 | 
			
		||||
                    rear.prev = null;
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                rear = rPrev;    // 更新尾结点
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            queSize--; // 更新队列长度
 | 
			
		||||
            return val;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队首出队 */
 | 
			
		||||
        public int? pollFirst()
 | 
			
		||||
        {
 | 
			
		||||
            return poll(true);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 队尾出队 */
 | 
			
		||||
        public int? pollLast()
 | 
			
		||||
        {
 | 
			
		||||
            return poll(false);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 访问队首元素 */
 | 
			
		||||
        public int? peekFirst()
 | 
			
		||||
        {
 | 
			
		||||
            return isEmpty() ? null : front.val;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 访问队尾元素 */
 | 
			
		||||
        public int? peekLast()
 | 
			
		||||
        {
 | 
			
		||||
            return isEmpty() ? null : rear.val;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        /* 返回数组用于打印 */
 | 
			
		||||
        public int[] toArray()
 | 
			
		||||
        {
 | 
			
		||||
            ListNode node = front;
 | 
			
		||||
            int[] res = new int[size()];
 | 
			
		||||
            for (int i = 0; i < res.Length; i++)
 | 
			
		||||
            {
 | 
			
		||||
                res[i] = node.val;
 | 
			
		||||
                node = node.next;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            return res;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public class linkedlist_deque
 | 
			
		||||
    {
 | 
			
		||||
        [Test]
 | 
			
		||||
        public void Test()
 | 
			
		||||
        {
 | 
			
		||||
            /* 初始化双向队列 */
 | 
			
		||||
            LinkedListDeque deque = new LinkedListDeque();
 | 
			
		||||
            deque.pushLast(3);
 | 
			
		||||
            deque.pushLast(2);
 | 
			
		||||
            deque.pushLast(5);
 | 
			
		||||
            Console.WriteLine("双向队列 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 访问元素 */
 | 
			
		||||
            int? peekFirst = deque.peekFirst();
 | 
			
		||||
            Console.WriteLine("队首元素 peekFirst = " + peekFirst);
 | 
			
		||||
            int? peekLast = deque.peekLast();
 | 
			
		||||
            Console.WriteLine("队尾元素 peekLast = " + peekLast);
 | 
			
		||||
 | 
			
		||||
            /* 元素入队 */
 | 
			
		||||
            deque.pushLast(4);
 | 
			
		||||
            Console.WriteLine("元素 4 队尾入队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
            deque.pushFirst(1);
 | 
			
		||||
            Console.WriteLine("元素 1 队首入队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 元素出队 */
 | 
			
		||||
            int? pollLast = deque.pollLast();
 | 
			
		||||
            Console.WriteLine("队尾出队元素 = " + pollLast + ",队尾出队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
            int? pollFirst = deque.pollFirst();
 | 
			
		||||
            Console.WriteLine("队首出队元素 = " + pollFirst + ",队首出队后 deque = " + string.Join(" ", deque.toArray()));
 | 
			
		||||
 | 
			
		||||
            /* 获取双向队列的长度 */
 | 
			
		||||
            int size = deque.size();
 | 
			
		||||
            Console.WriteLine("双向队列长度 size = " + size);
 | 
			
		||||
 | 
			
		||||
            /* 判断双向队列是否为空 */
 | 
			
		||||
            bool isEmpty = deque.isEmpty();
 | 
			
		||||
            Console.WriteLine("双向队列是否为空 = " + isEmpty);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user