C# 数据结构基础-实现循环队列

队列
    队列的概念是先进先出,这个应该不用多说了。看下面那个从网上找的现成图片。

循环队列
    循环队列在逻辑上将队列中的数据摆成环形,如下图:

 

下面直接上代码。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
队列
    队列的概念是先进先出,这个应该不用多说了。看下面那个从网上找的现成图片。
 
循环队列
    循环队列在逻辑上将队列中的数据摆成环形,如下图:
 
 
下面直接上代码。
 
[csharp] view plain copy 在CODE上查看代码片派生到我的代码片
/// <summary> 
    /// 循环队列 
    /// 2015年1月4日 
    /// </summary> 
    /// <typeparam name="T"></typeparam> 
    public class MyCircleQueue<T> 
    
        /// <summary> 
        /// 队列数组 
        /// </summary> 
        private T[] _queue; 
        /// <summary> 
        /// 队首索引 
        /// </summary> 
        private int _front; 
        /// <summary> 
        /// 队尾索引 
        /// </summary> 
        private int _rear; 
           
        /// <summary> 
        /// 队列的内存大小,但实际可用大小为_capacity-1 
        /// </summary> 
        private int _capacity; 
   
        public MyCircleQueue(int queueSize) 
        
            if (queueSize < 1) 
                throw new IndexOutOfRangeException("传入的队列长度不能小于1。"); 
   
            //设置队列容量 
            _capacity = queueSize; 
               
            //创建队列数组 
            _queue = new T[queueSize]; 
   
            //初始化队首和队尾索引 
            _front = _rear = 0; 
        
   
        /// <summary> 
        /// 添加一个元素 
        /// </summary> 
        /// <param name="item"></param> 
        public void Push(T item) 
        
            //队列已满 
            if (GetNextRearIndex() == _front) 
            
                //扩大数组 
                T[] newQueue = new T[2 * _capacity]; 
                   
                if (newQueue == null
                    throw new ArgumentOutOfRangeException("数据容量过大,超出系统内存大小。"); 
                //队列索引尚未回绕 
                if (_front == 0) 
                
                    //将旧队列数组数据转移到新队列数组中 
                    Array.Copy(_queue, newQueue, _capacity); 
                
                else 
                
                    //如果队列回绕,刚需拷贝再次, 
                    //第一次将队首至旧队列数组最大长度的数据拷贝到新队列数组中 
                    Array.Copy(_queue, _front, newQueue, _front, _capacity - _rear - 1); 
                    //第二次将旧队列数组起始位置至队尾的数据拷贝到新队列数组中 
                    Array.Copy(_queue, 0, newQueue, _capacity, _rear + 1); 
                    //将队尾索引改为新队列数组的索引 
                    _rear = _capacity + 1; 
                
   
                _queue = newQueue; 
                _capacity *= 2; 
            
   
            //累加队尾索引,并添加当前项 
            _rear = GetNextRearIndex(); 
            _queue[_rear] = item; 
        
   
        /// <summary> 
        /// 获取队首元素 
        /// </summary> 
        /// <returns></returns> 
        public T FrontItem() 
        
            if (IsEmpty()) 
                throw new ArgumentOutOfRangeException("队列为空。"); 
               
            return _queue[GetNextFrontIndex()]; 
        
   
        /// <summary> 
        /// 获取队尾元素 
        /// </summary> 
        /// <returns></returns> 
        public T RearItem() 
        
            if (IsEmpty()) 
                throw new ArgumentOutOfRangeException("队列为空。"); 
   
            return _queue[_rear]; 
        
   
        /// <summary> 
        /// 弹出一个元素 
        /// </summary> 
        /// <returns></returns> 
        public T Pop() 
        
            if (IsEmpty()) 
                throw new ArgumentOutOfRangeException("队列为空。"); 
   
            _front = GetNextFrontIndex(); 
            return _queue[_front]; 
        
   
        /// <summary> 
        /// 队列是否为空 
        /// </summary> 
        /// <returns></returns> 
        public bool IsEmpty() 
        
            return _front == _rear; 
        
        /// <summary> 
        /// 获取下一个索引 
        /// </summary> 
        /// <returns></returns> 
        private int GetNextRearIndex() 
        
            if (_rear + 1 == _capacity) 
            
                return 0; 
            
            return _rear + 1; 
        
   
        /// <summary> 
        /// 获取下一个索引 
        /// </summary> 
        /// <returns></returns> 
        private int GetNextFrontIndex() 
        
            if (_front + 1 == _capacity) 
            
                return 0; 
            
            return _front + 1; 
        
    

  

转自:http://blog.csdn.net/liguo9860/article/details/42395009

posted @   遥望星空  阅读(5086)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 25岁的心里话
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
历史上的今天:
2011-03-30 black.lst 丢失或被破坏,怎么解决
点击右上角即可分享
微信分享提示