数据结构和算法 – 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),但与队列不同的是,插入操作在两 ...
随机推荐
- Fedora 24最新工作站版本之四大重要改进
导读 2014年,Fedora.next倡议正式开始建立Fedora Linux未来十年的发展规划.从本质上讲,这项规划旨在进一步使Fedora不再只是一套汇聚多种开源产品的通用库(例如Debian) ...
- navigationcontroller剖析
概述: 系统原生的navigationcontroller非常强大, 几乎所有的程序都基于系统的导航控制器做开发 它的navigationbar的有2种形态 navigationbar的frame其实 ...
- PYTHON seek()tell()语句
print(f.tell()) # 显示当前位置 f.seek(0) #回到某一起点
- (原创)android中使用相机的两种方式
在社交类应用或扫描二维码的场合都需要用到手机上的摄像头 在程序中启用这一硬件主要有两类方法 1.发送intent启动系统自带的摄像应用 此应用的AndroidManifest中的intent-filt ...
- Codeforces 727 F. Polycarp's problems
Description 有一个长度为 \(n\) 有正负权值的序列,你一开始有一个值,每次到一个权值就加上,最少需要删掉多少数值才能到序列末尾.\(n \leqslant 750,m \leqslan ...
- 3.创建基本的AngularJS应用
1.1.模块 AngularJS引入了代表应用程序组件的模块的概念.模块提供命名空间,以基于模型的名称来引用指令,范围和其他组件.使得包装和再利用应用程序的部件更容易. AngularJS中,每个视图 ...
- python 端口扫描仪
思路:使用socket进行连接测试,即客户端连接服务器. 核心代码如下: from socket import * def try_port(ip,port,protocol = SOCK_STREA ...
- faac编码aac
// faacode.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <faac.h> #include &l ...
- 同级兄弟元素之间的CSS控制
为了实现这个导航效果:选中菜单中某一项,隐藏掉自身的左边背景线条,同时让他的下一个兄弟元素也隐藏掉线条. 有一种选择器就叫兄弟元素选择器,分为临近兄弟和普通兄弟. 临近兄弟:用 + 表示,只匹配该元素 ...
- Linux下查看机器公网IP
http://jimingsong.iteye.com/blog/1188905 curl http://ifconfig.me