数据结构和算法 – 3.堆栈和队列
1.栈的实现
后进先出

自己实现栈的代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections; namespace 数据结构和算法
{
//栈
class CStack
{
private ArrayList list;
private int p_index;
public CStack()
{
list = new ArrayList();
p_index = -1;
}
public int count
{
get { return list.Count; }
} public void Push(object item)
{
list.Add(item);
p_index++;
} public object Pop()
{
object obj = list[p_index];
list.RemoveAt(p_index);
p_index--;
return obj;
} public void Clear()
{
list.Clear();
p_index = -1;
}
//查看
public object Peek()
{
return list[p_index];
} static void Main(string[] args)
{
//回文: sees倒过来还是sees
CStack alist = new CStack();
string ch;
string word = "sees";
bool ispalindrome = true;
for (int i = 0; i < word.Length; i++)
{
alist.Push(word.Substring(i, 1));
}
int pos = 0;
while (alist.count > 0)
{
ch = alist.Pop().ToString();
if (ch!=word.Substring(pos,1))
{
ispalindrome = false;
break;
}
pos++;
}
if (ispalindrome)
{
Console.WriteLine(word+" 是回文.");
}
else
{
Console.WriteLine(word + " 不是回文.");
} Console.ReadKey();
}
}
}

2.Stack类(堆栈)
Stack 类是 ICollection 接口的一个实现。它代表了一个 LIFO 群集或一个堆栈。此类在.NET 框架中是作为循环缓冲来实现的。这使得能动态地分配进栈数据项的空间。
Stack 类包含进栈方法、出栈方法以及取值方法。此外,还有用于确定堆栈内元素数量的方法,清除堆栈全部数值的方法,以及把堆栈数值作为数组返回的方法。
CopyTo 方法和 ToArray 方法
CopyTo 方法会把堆栈内的内容复制到一个数组中。数组必须是 Object 类型,因为这是所有堆栈对象的数据类型。此方法会取走两个参数:一个数组和开始放置堆栈元素的数组的起始索引。堆栈内元素按照 LIFO 的顺序进行复制操作,就好像对它们进行出栈操作一样。下面这段代码说明了 CopyTo 方法的调用:
Stack myStack = new Stack();
for (int i = 20; i > 0; i--)
myStack.Push(i);
object[] myArray = new object[myStack.Count];
myStack.CopyTo(myArray, 0);
ToArray 方法的工作原理与 CopyTo 方法类似。但是用户无法指定数组的起始索引位置,而是需要在赋值语句中创建新的数组。实例如下所示:
Stack myStack = new Stack();
for (int i = 0; i > 0; i++)
myStack.Push(i);
object[] myArray = new object[myStack.Count];
myArray = myStack.ToArray();
堆栈的实际操作
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions; namespace 数据结构和算法
{
class 堆栈的操作
{
static void Main()
{
Stack nums = new Stack();
Stack ops = new Stack();
string expression = "5 + 10 + 15 +20";
Calculate(nums, ops, expression); Console.WriteLine("Pop之前的数据:" + nums.Peek());
nums.Push("1");
Console.WriteLine("Pop的数据:" + nums.Pop());
//nums.Push("1");
Console.WriteLine("Pop之后的数据:" + nums.Peek());
nums.Clear();
if (nums.Count == 0)
{
Console.WriteLine("Clear之后的数据为空");
}
else
Console.WriteLine("Clear之后的数据是否为空" + nums.Peek());
Console.Read();
} //IsNumeric isn'tbuilt into C# so we must define it
static bool IsNumeric(string input)
{
bool flag = true;
string pattern = (@"^\d+$");
Regex validate = new Regex(pattern);
if (!validate.IsMatch(input))
{
flag = false;
}
return flag;
} static void Calculate(Stack N, Stack O, string exp)
{
string ch, token = "";
for (int p = 0; p < exp.Length; p++)
{
ch = exp.Substring(p, 1);
if (IsNumeric(ch))
{
token += ch; //+=
}
if (ch == " " || p == (exp.Length - 1))
{
if (IsNumeric(token))
{
N.Push(token);
token = "";
}
}
else if (ch == "+" || ch == "-" || ch == "*" || ch == "/")
{
O.Push(ch);
}
if (N.Count == 2)
{
Compute(N, O);
}
}
} static void Compute(Stack N, Stack O)
{
int oper1, oper2;
string oper;
oper1 = Convert.ToInt32(N.Pop());
oper2 = Convert.ToInt32(N.Pop());
oper = Convert.ToString(O.Pop());
switch (oper)
{
case "+":
N.Push(oper1 + oper2);
break;
case "-":
N.Push(oper1 - oper2);
break;
case "*":
N.Push(oper1 * oper2);
break;
case "/":
N.Push(oper1 / oper2);
break;
}
}
}
}

3.队列
先进先出
enQueue 排队
deQueue 出队
4.Queue类 (队列)
在对一个新的 Queue 对象实例化的时候,队列默认的容量是 32 个数据项。根据定义,当队列已满时,其容量会双倍增长。这就意味着当队列最初达到满容量时,其新的容量值会变为 64。但是大家可以不用受这些数值的限制。
在实例化对队列时,大家可以指定一个不同的初始容量值。
Queue myQueue = new Queue(100);
这个设置把队列的容量值设为了 100 个数据项。当然,大家也可以改变增长的倍数。增长倍数是传递给构造器的第二个参数,如下所示:
Queue myQueue = new Queue(32, 3);
用队列存储数据
基数排序是通过对一组数据进行两遍排序来操作的。在这种情况下,整数的取值范围是从 0 到 99。第一遍是基于个位上的数字进行排序,而第二遍则是基于十位上的数字进行排序。然后,根据这些位置上的每个数字来把每一个数放置在一个箱子内。
假设有下列这些数: 91、 46、 85、 15、 92、 35、 31、 22。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace 数据结构和算法
{
class 用队列存储数据
{
enum DigitType {
//个位
ones = 1,
//十位
tens = 10
} //打印排序后的内容
static void DisplayArray(int[] n)
{
for (int x = 0; x <= n.GetUpperBound(0); x++)
Console.Write(n[x] + " ");
} //排序
static void RSort(Queue[] que, int[] n, DigitType digit)
{
int snum;//下标 for (int x = 0; x <= n.GetUpperBound(0); x++)
{
if (digit == DigitType.ones)
snum = n[x] % 10;
else
snum = n[x] / 10;
que[snum].Enqueue(n[x]);
}
} static void BuildArray(Queue[] que, int[] n)
{
int y = 0;
for (int x = 0; x <= 9; x++)
//que的下标count大于0的时候,替换n
while (que[x].Count > 0)
{
n[y] =
Int32.Parse(que[x].Dequeue().ToString());
y++;
}
} static void Main(string[] args)
{
Queue[] numQueue = new Queue[10];
int[] nums = new int[] { 91, 46, 85, 15, 92, 35, 31, 22 };
int[] random = new Int32[99]; DisplayArray(nums); // Display original list
for (int i = 0; i < 10; i++)
numQueue[i] = new Queue(); RSort(numQueue, nums, DigitType.ones);
//numQueue, nums, 1
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("第1次排序: ");
//打印排序后的内容
DisplayArray(nums);
// Second pass sort
RSort(numQueue, nums, DigitType.tens);
BuildArray(numQueue, nums);
Console.WriteLine();
Console.WriteLine("第2次排序结果: ");
//打印排序后的内容
DisplayArray(nums);
Console.WriteLine();
Console.Write("Press enter to quit");
Console.Read();
}
}
}


5. Queue 类的优先队列
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text; namespace 数据结构和算法
{
public struct pqItem
{
//优先级
public int priority;
public string name;
} public class PQueue : Queue
{
static void Main()
{
PQueue erwait = new PQueue();
pqItem[] erPatient = new pqItem[3];
pqItem nextPatient;
erPatient[0].name = "刘在锡";
erPatient[0].priority = 1;
erPatient[1].name = "李光洙";
erPatient[1].priority = 0;
erPatient[2].name = "金钟国";
erPatient[2].priority = 3; for (int x = 0; x <= erPatient.GetUpperBound(0); x++)
erwait.Enqueue(erPatient[x]); nextPatient = (pqItem)erwait.Dequeue(); Console.WriteLine(nextPatient.name);
Console.Read();
} public PQueue()
{ } //重写出队
public override object Dequeue()
{
object[] items; int min;
items = this.ToArray();
//假设第1个最小
min = ((pqItem)items[0]).priority; for (int x = 1; x <= items.GetUpperBound(0); x++)
if (((pqItem)items[x]).priority < min)
{
min = ((pqItem)items[x]).priority;
} this.Clear(); int x2; for (x2 = 0; x2 <= items.GetUpperBound(0); x2++)
if (((pqItem)items[x2]).priority == min && ((pqItem)items[x2]).name != "")
this.Enqueue(items[x2]); return base.Dequeue();
}
} }

数据结构和算法 – 3.堆栈和队列的更多相关文章
- JavaScript 版数据结构与算法(二)队列
今天,我们要讲的是数据结构与算法中的队列. 队列简介 队列是什么?队列是一种先进先出(FIFO)的数据结构.队列有什么用呢?队列通常用来描述算法或生活中的一些先进先出的场景,比如: 在图的广度优先遍历 ...
- JS数据结构及算法(二) 队列
队列是遵循先进先出的一种数据结构,在尾部添加新元素,并从顶部移除元素. 1.普通队列 function Queue() { this.items = []; } Queue.prototype = { ...
- 用JS描述的数据结构及算法表示——栈和队列(基础版)
前言:找了上课时数据结构的教程来看,但是用的语言是c++,所以具体实现在网上搜大神的博客来看,我看到的大神们的博客都写得特别好,不止讲了最基本的思想和算法实现,更多的是侧重于实例运用,一边看一边在心里 ...
- Java数据结构和算法(五)——队列
前面一篇博客我们讲解了并不像数组一样完全作为存储数据功能,而是作为构思算法的辅助工具的数据结构——栈,本篇博客我们介绍另外一个这样的工具——队列.栈是后进先出,而队列刚好相反,是先进先出. 1.队列的 ...
- 用Python实现的数据结构与算法:堆栈
一.概述 堆栈(Stack)是一种后进先出(LIFO)的线性数据结构,对堆栈的插入和删除操作都只能在栈顶(top)进行. 二.ADT 堆栈ADT(抽象数据类型)一般提供以下接口: Stack() 创建 ...
- 数据结构与算法JavaScript描述——使用队列
1.使用队列:方块舞的舞伴分配问题 前面我们提到过,经常用队列模拟排队的人.下面我们使用队列来模拟跳方块舞的人.当 男男女女来到舞池,他们按照自己的性别排成两队.当舞池中有地方空出来时,选两个队 列中 ...
- 用Python实现的数据结构与算法:双端队列
一.概述 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的线性数据结构.双端队列也拥有两端:队首(front).队尾(rear),但与队列不同的是,插入操作在两 ...
- golang数据结构和算法之QueueLinkedList链表队列
队列和堆栈不一样的地方在于进出顺序: 堆栈是后进先出, 队列是先进先出. QueueLinkedList.go package QueueLinkedList type Node struct { d ...
- Python实现的数据结构与算法之双端队列详解
一.概述 双端队列(deque,全名double-ended queue)是一种具有队列和栈性质的线性数据结构.双端队列也拥有两端:队首(front).队尾(rear),但与队列不同的是,插入操作在两 ...
随机推荐
- Unity开发-你必须知道的优化建议
转自:http://blog.csdn.net/leonwei/article/details/18042603 最近研究U3D开发,个人认为,精通一种新的技术,最快最好的方法就是看它的documen ...
- leetcode 141. Linked List Cycle
Given a linked list, determine if it has a cycle in it. Follow up:Can you solve it without using ext ...
- All Kind Of Conference(随时更新...)
收集一些前端开发的各种会议,里面有视频或者PPT,随时查看都还是很有收获的.还有要向这些演讲的前辈看齐- AC 2015:http://ac.alloyteam.com/2015/ AC 2016:h ...
- Unity3D获取Andorid设备返回键,主页键等功能
在Unity开发中捕捉Android的常用事件其实很简单 在新建的脚本文件中就加入: 比如: // 返回键 if ( Application.platform == RuntimePlatform.A ...
- SpringMVC基础入门
一.SpringMVC基础入门,创建一个HelloWorld程序 1.首先,导入SpringMVC需要的jar包. 2.添加Web.xml配置文件中关于SpringMVC的配置 1 2 3 4 5 6 ...
- Python自动化之sqlalchemy(修改和查询)
修改 my_user = Session.query(User).filter_by(name="alex").first() my_user.name = "Alex ...
- javascript 常用技巧
1. 将彻底屏蔽鼠标右键 oncontextmenu=”window.event.returnValue=false” < table border oncontextmenu=return(f ...
- String和StringBuffer的转换
从String到StringBuffer: StringBuffer sb = New StringBuffer("abcd");从StringBuffer到String: Str ...
- CEF3开发者系列之类和接口
CEF3基本的框架包含C/C++程 序接口,通过本地库的接口来实现,而这个库则会隔离宿主程序和 Chromium&Webkit的操作细节.它在浏览器控件和宿主程序之间提供紧密的整合,它支持用户 ...
- NGUI 不写一行代码实现翻拍效果
正面UI添加一个TweenRotation组件,取消掉Active状态 ,To参数改成0,90,0) 背面UI添加一个TweenRotation组件,取消掉Active状态, From参数改成0,27 ...