码迷,mamicode.com
首页 > 编程语言 > 详细

数据结构与算法之栈

时间:2015-10-18 16:52:47      阅读:242      评论:0      收藏:0      [点我收藏+]

标签:

  前言:我也是即学即写的,难免有错误。欢迎之处这篇博文的不足之处。

一、什么是栈?

  栈是数据结构的一种,他的原理就是后进先出(先进后出是一样的道理),如图(无图言屌)技术分享

  技术分享

  看到没,你如果把栈当成一个开口向上的容器的话,你最先存储的a1要想取出来,必须把上面的元素都取出来,而你最后一个存储的a5元素却可以第一个取出来。这就是后进先出。

PS:我这里的top是指向栈顶元素的,这里用到的top初值是-1.有的书中(好像是严蔚敏的)的top的初始值是0.所以top指向栈顶元素的上一个存储单元。我个人觉得还是top初始值为-1比较好。关于这个知识点下面详讲。

二、为什么要学栈?学了有什么用?

   查了好多资料,我暂时不知道怎么更好的解释,待补充。

三、栈怎么用代码去实现?

  终于到代码阶段了,栈分为顺序栈和链栈(是不是与顺序表,链表很相似?答案是相似度很高啊...)

首先来看看BCL中的栈的基本操作:BCL就是visual studio 里面封装的栈Stack。直接拿来用就好。

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5 
 6             Stack<int> stack = new Stack<int>();   //这是定义一个栈的对象stack
 7             stack.Push(6);                         //Push就是入栈的操作,它是没有返回值的,含一个参数,就是你要存储进栈里面的数值。我的栈是int类型的所以我Push一个6
 8             stack.Pop();                           //Pop有返回值,返回栈顶的元素并且把栈顶元素删掉,top指向下一个元素
 9             stack.Peek();                //Peek有返回值,返回栈顶元素。与Pop的区别在于Peek不删除栈顶元素。
10             stack.Count();                         //有返回值,返回栈里面的元素个数
11             stack.Clear();                         //清空栈
12       
13         }
14     }


这几个是比较常见的,还有一些其他的就不多叙述了。看到这里你有可能会说既然visual studio已经封装好栈了我直接用不就得了,那我不是已经学会栈了吗,真简单。是的,你现在已经学会栈这个数据结构了,但是算法呢?Pop,Peek它们内部是怎么实现的你知道吗?如果在某个偶然的条件下,BCL类不能用了,怎么办?所以要学这个算法,至少你可以自己写一个栈,用自己的代码,让BCL凉快去吧。(了解内部的构成后,其实用BCL也没什么不对。人家visual studio封装好的不用白不用...)技术分享

 

顺序栈:

首先新建一个接口:

1 interface IStack<T>        //这里的T是泛型的意思,就是你定义成什么类型T就是什么类型,相当于T是类型的一个代表
2     {
3         int Count{get; }
4         bool IsEmpty();
5         int GetLength();
6         void Push(T item);
7         T Pop();
8         T Peek();
9     }

然后新建一个类作为顺序栈,这个类继承接口:

 1 class MyStack <T>:IStack<T>
 2     {
 3         private T [] Data;
 4         private int top;
 5 
 6         public MyStack(int size)
 7         {
 8             Data = new T[size];
 9             top = -1;
10         }
11         public MyStack():this(10)
12         {
13             top = -1;
14         }
15 
16         public int Count
17         {
18             get { return top + 1; }
19         }
20 
21         public bool IsEmpty()
22         {
23             return Count == 0;
24         }
25 
26         public int GetLength()
27         {
28             return Count;
29         }
30 
31         public void Push(T item)
32         {
33             Data[top + 1] = item;
34             top++;
35         }
36 
37         public T Pop()
38         {
39             T item = Data[top];
40             top--;
41             return item;
42         }
43 
44         public T Peek()
45         {
46             return Data[top];
47         }
48     }

完成了。在控制台里面调用一下看看行不行

 1  class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5   
 6             //顺序栈     
 7            IStack<int> stack = new MyStack<int>();
 8          
 9             stack.Push(3);
10             stack.Push(8);
11             Console.WriteLine(stack.Count);
12             Console.WriteLine(stack.Peek());
13             Console.WriteLine(stack.Count);
14             Console.WriteLine(stack.Pop());
15             Console.WriteLine(stack.Count);
16             Console.ReadLine();
17           
18         }
19     }

运行结果:

技术分享

 

链栈:

新建一个类作为链栈的节点:

 1  class Node<T>
 2     {
 3         private T data;
 4         public T Data
 5         {
 6             get { return data; }
 7             set { data = value; }
 8         }
 9 
10         private Node<T> next;
11         internal Node<T> Next
12         {
13             get { return next; }
14             set { next = value; }
15         }
16         
17         public Node()
18         {
19             data = default(T);
20             next = null;
21         }
22         public Node(T data)
23         {
24             this.data = data;
25             next = null;
26         }
27         public Node(T data, Node<T> next)
28         {
29             this.data = data;
30             this.next = next;
31         }
32         public Node(Node<T> next)
33         {
34             this.next = next;
35             data = default(T);
36         }
37 
38 
39     }

新建一个类作为链栈功能的实现,还是继承那个接口:

 1 class ListStack<T>:IStack<T>
 2     {
 3         private Node<T> top;
 4         private int count;
 5 
 6         public int Count
 7         {
 8             get { return count; }
 9         }
10 
11         public bool IsEmpty()
12         {
13             return count == 0;
14         }
15 
16         public int GetLength()
17         {
18             return count;
19         }
20 
21         public void Push(T item)
22         {
23             Node<T> newNode = new Node<T>(item);
24             newNode.Next = top;
25             top = newNode;
26             count++;
27         }
28 
29         public T Pop()
30         {
31             T data = top.Data;
32             top=top.Next;
33             count--;
34             return data;
35         }
36 
37         public T Peek()
38         {
39             return top.Data;
40         }
41     }


在控制台运行试试

 1 class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5           
 6             //链栈
 7             IStack<int> stack = new ListStack<int>();
 8             stack.Push(3);
 9             stack.Push(8);
10             Console.WriteLine(stack.Count);
11             Console.WriteLine(stack.Peek());
12             Console.WriteLine(stack.Count);
13             Console.WriteLine(stack.Pop());
14             Console.WriteLine(stack.Count);
15             Console.ReadLine();
16           
17         }
18     }

运行结果:

技术分享

 

顺序栈和链栈都成功了。

 

 四、重点难点详解。

top初始值为-1或者是0,这都是什么和什么啊

 

 

top初始值为-1:

 

技术分享

当你存储元素之后,top++,这时候top一直是指向栈顶元素的,这样做的好处是,栈的个数是top,而且stack[top]直接就是栈顶元素。缺点是调用Push时要Push(++top),栈的个数也是top+1.

 

技术分享

top初始值为0:

 

 

技术分享

 

top初始值为0的好处呢,就是Push的话直接Push(top),然后再top++;和栈的元素个数是top。稍微麻烦的是栈顶元素是stack[top-1].

 

技术分享

其实top的初始值是-1还是0无关紧要,按照自己的习惯来就好,我是更倾向于top=-1;

 

 

顺序栈像一个只有一端开口的数组一样,链栈是怎么回事呀?

 

你可以把链栈理解为一个一个节点Node链接起来了,一个节点应该包括两部分,data和next.data里面装的是本节点的数据,next里面存储的是上一个节点的

 

 

技术分享

 链栈是这样进行的

技术分享

 

数据结构与算法之栈

标签:

原文地址:http://www.cnblogs.com/yunquan/p/4889029.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!