数据结构基础温故-2.栈
2015-07-04 01:55
477 查看
现实生活中的事情往往都能总结归纳成一定的数据结构,例如餐馆中餐盘的堆叠和使用,羽毛球筒里装的羽毛球等都是典型的栈结构。而在.NET中,值类型在线程栈上进行分配,引用类型在托管堆上进行分配,本文所说的“栈”正是这种数据结构。栈和队列都是常用的数据结构,它们的逻辑结构与线性表相通,不同之处则在于操作受某种特殊限制。因此,栈和队列也被称为操作受限的线性表。这里,我们首先来了解一下栈。
View Code
(5)简单的功能测试
这里跟顺序存储结构的测试代码一致,就不再贴出来,直接看运行结果吧:
由上图的计算过程可知,D进制各位数的产生顺序是从低位到高位,而输出顺序却是从高位到低位,刚好和计算过程是相反的,因此可以利用栈进行逆序输出。
这里考虑到输出,所以使用了char类型作为节点数据类型,因此需要考虑ASCII码中的数字型字符与字母型字符。运行结果如下图所示:
①10进制数:350=>8进制数:536
②10进制数:72=>16进制数:48
③10进制数:38=>2进制数:100110
(1)Push方法源码
(2)Pop方法源码
可以看出,在.NET中Stack的实现是基于数组来实现的,在初始化时为其设置了一个默认的数组大小,在Push方法中当元素个数达到数组长度时,扩充2倍容量,然后将原数组拷贝到新的数组中。Pop方法中则跟我们刚刚实现的代码基本相同。
(2)陈广,《数据结构(C#语言描述)》
(3)段恩泽,《数据结构(C#语言版)》
(4)yangecnu,《浅谈算法与数据结构:—栈和队列》
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
一、栈的概念及操作
1.1 栈的基本特征
/// <summary> /// 基于链表的栈节点 /// </summary> /// <typeparam name="T">元素类型</typeparam> public class Node<T> { public T Item { get; set; } public Node<T> Next { get; set; } public Node(T item) { this.Item = item; } public Node() { } } /// <summary> /// 基于链表的栈实现 /// </summary> /// <typeparam name="T">类型</typeparam> public class MyLinkStack<T> { private Node<T> first; private int index; public MyLinkStack() { this.first = null; this.index = 0; } /// <summary> /// 入栈 /// </summary> /// <param name="item">新节点</param> public void Push(T item) { Node<T> oldNode = first; first = new Node<T>(); first.Item = item; first.Next = oldNode; index++; } /// <summary> /// 出栈 /// </summary> /// <returns>出栈元素</returns> public T Pop() { T item = first.Item; first = first.Next; index--; return item; } /// <summary> /// 是否为空栈 /// </summary> /// <returns>true/false</returns> public bool IsEmpty() { return this.index == 0; } /// <summary> /// 栈中节点个数 /// </summary> public int Size { get { return this.index; } } }
View Code
(5)简单的功能测试
这里跟顺序存储结构的测试代码一致,就不再贴出来,直接看运行结果吧:
三、栈的基本应用
栈的应用场景很多,最常见的莫过于递归操作了,另外在运算表达式的求值上也有应用。这里看一个最经典的应用场景,进制转换问题。讲一个非负的十进制整数N转换成其他D进制数是计算机计算的一个基本问题,如(135)10进制=(207)8进制。最简单的解决办法就是连续取模%和整除/,例如将10进制的50转换为2进制数的过程如下图所示:由上图的计算过程可知,D进制各位数的产生顺序是从低位到高位,而输出顺序却是从高位到低位,刚好和计算过程是相反的,因此可以利用栈进行逆序输出。
private static string DecConvert(int num, int dec) { if (dec < 2 || dec > 16) { throw new ArgumentOutOfRangeException("dec", "只支持将十进制数转换为二进制到十六进制数"); } MyLinkStack<char> stack = new MyLinkStack<char>(); int residue; // 余数入栈 while (num != 0) { residue = num % dec; if (residue >= 10) { // 如果是转换为16进制且余数大于10则需要转换为ABCDEF residue = residue + 55; } else { // 转换为ASCII码中的数字型字符1~9 residue = residue + 48; } stack.Push((char)residue); num = num / dec; } // 反序出栈 string result = string.Empty; while (stack.Size > 0) { result += stack.Pop(); } return result; }
这里考虑到输出,所以使用了char类型作为节点数据类型,因此需要考虑ASCII码中的数字型字符与字母型字符。运行结果如下图所示:
①10进制数:350=>8进制数:536
②10进制数:72=>16进制数:48
③10进制数:38=>2进制数:100110
四、.NET中的Stack<T>
在.NET中,微软已经为我们提供了一个强大的栈类型:Stack<T>,这里我们使用Reflector工具查看其具体实现,具体看看Push和Pop两个方法,其他的各位园友可以自己去查看。(1)Push方法源码
public void Push(T item) { if (this._size == this._array.Length) { T[] destinationArray = new T[(this._array.Length == 0) ? 4 : (2 * this._array.Length)]; Array.Copy(this._array, 0, destinationArray, 0, this._size); this._array = destinationArray; } this._array[this._size++] = item; this._version++; }
(2)Pop方法源码
public T Pop() { if (this._size == 0) { ThrowHelper.ThrowInvalidOperationException(ExceptionResource.InvalidOperation_EmptyStack); } this._version++; T local = this._array[--this._size]; this._array[this._size] = default(T); return local; }
可以看出,在.NET中Stack的实现是基于数组来实现的,在初始化时为其设置了一个默认的数组大小,在Push方法中当元素个数达到数组长度时,扩充2倍容量,然后将原数组拷贝到新的数组中。Pop方法中则跟我们刚刚实现的代码基本相同。
参考资料
(1)程杰,《大话数据结构》(2)陈广,《数据结构(C#语言描述)》
(3)段恩泽,《数据结构(C#语言版)》
(4)yangecnu,《浅谈算法与数据结构:—栈和队列》
作者:周旭龙
出处:http://edisonchou.cnblogs.com
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
相关文章推荐
- 数据结构—基础知识
- 【数据结构】利用栈来求算术表达式的值
- redis基础数据结构和数据对象
- 重温《大话数据结构》笔记一 单链表链式存储结构的操作代码
- malloc 结合内部数据结构讲解逻辑实现原理
- MySQL索引背后的数据结构及算法原理
- libeven入门数据结构bufferevent
- COJ976 WZJ的数据结构(负二十四)
- 数据结构习题之树
- COJ977 WZJ的数据结构(负二十三)
- COJ978 WZJ的数据结构(负二十二)
- Codeforces Round #309 (Div. 1) D. Nudist Beach 数据结构
- Trie树学习--数据结构一发
- 数据结构:链表,栈堆,队列
- 数据结构基础温故-1.线性表(下)
- 数据结构之---C语言实现哈夫曼树和编码
- 离散数学Notes
- Codeforces Round #311 (Div. 2) E. Ann and Half-Palindrome (DP+字典树)
- 【数据结构】堆栈和队列
- 2015华为软赛(四)——数据结构设计