概念:
栈(stack)又名堆栈,它是一种运算受限的线性表。其限制是仅允许在表的一端进行插入和删除运算。这一端被称为栈顶,相对地,把另一端称为栈底。向一个栈插入新元素又称作进栈、入栈或压栈,它是把新元素放到栈顶元素的上面,使之成为新的栈顶元素;从一个栈删除元素又称作出栈或退栈,它是把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
我们通常说堆栈那么其实他俩并非一个概念,我们从编译程序占用的内存分配来了解一下。
栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
堆区(heap)— 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表。
全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 - 程序结束后有系统释放。
文字常量区(CONST)—常量字符串就是放在这里的。 程序结束后由系统释放.
程序代码区(Program)—存放函数体的二进制代码。
顺序栈(SequenceStack):用一片连续的存储空间来存储栈中的数据元素。类似于顺序表,用一维数组来存放栈中的数据元素。缺点:浪费存储空间。
链栈(LinkedStack):用链式存储结构来存储的栈.链栈通常用单链表来表示。
C#下代码的实现:
公共接口:
internal interface IStack<T>
{
void Push(T item);
T Pop();
T GetTop();
int GetLength();
bool IsEmpty();
void Clear();
}
顺序栈:
/*
*
顺序栈
*
*/
namespace Data_Structure_Demo
{
using System;
public class SequenceStack<T> : IStack<T>
{
//栈的容量
//用于存储栈中数据元素
private readonly T[] stackData;
private int stackSize;
//栈顶元素index
private int stackTop;
/// <summary>
/// 构造函数 初始化一个顺序栈 给定存储空间 栈元素为空
/// </summary>
/// <param name="size"></param>
public SequenceStack(int size)
{
this.stackData = new T[size];
this.stackSize = size;
this.stackTop = -1;
}
public T this[int index]
{
get { return this.stackData[index]; }
set { this.stackData[index] = value; }
}
public int StackSize
{
get { return this.stackSize; }
set { this.stackSize = value; }
}
public int StackTop
{
get { return this.stackTop; }
}
public int GetLength()
{
return this.stackTop + 1;
}
public void Clear()
{
this.stackTop = -1;
}
public bool IsEmpty()
{
if (this.stackTop == -1)
{
return true;
}
return false;
}
public void Push(T value)
{
if (this.IsFull())
{
Console.WriteLine("Stack is Full!(SB 栈都满了还往里怼!)");
}
this.stackData[++this.stackTop] = value;
}
public T Pop()
{
T value = default(T);
if (this.IsEmpty())
{
Console.WriteLine("Stack is Empty!(si bu si sa 都没了取个鸡毛!)");
return default(T);
}
value = this.stackData[this.stackTop];
--this.stackTop;
return value;
}
public T GetTop()
{
if (this.IsEmpty())
{
Console.WriteLine("Stack is Empty !(si bu si sa 都没了取个鸡毛!)");
return default(T);
}
return this.stackData[this.stackTop];
}
public bool IsFull()
{
if (this.stackTop == this.stackSize - 1)
{
return true;
}
return false;
}
}
}
链栈:
LinkStackNode:
public class LinkStackNode<T>
{
//数据域
//引用域
public LinkStackNode()
{
this.Data = default(T);
this.Next = null;
}
public LinkStackNode(T val)
{
this.Data = val;
this.Next = null;
}
public LinkStackNode(T val, LinkStackNode<T> p)
{
this.Data = val;
this.Next = p;
}
//数据域属性
public T Data { get; set; }
//引用域属性
public LinkStackNode<T> Next { get; set; }
}
链栈实现:
public class LinkStack<T> : IStack<T>
{
private LinkStackNode<T> top; //栈顶指示器
private int size; //栈中元素的个数
//栈顶指示器属性
public LinkStackNode<T> Top
{
get { return top; }
set { top = value; }
}
//元素个数属性
public int Size
{
get { return size; }
set { size = value; }
}
public LinkStack()
{
top = null;
size = 0;
}
//判断链栈是否为空
public bool IsEmpty()
{
if ((top == null) && (size == 0))
return true;
else
return false;
}
public int GetLength()
{
return size;
}
public void Clear()
{
top = null;
size = 0;
}
//入栈操作
//在单链表的起始处插入一个结点
public void Push(T item)
{
LinkStackNode<T> q = new LinkStackNode<T>(item);
if (top == null)
{
top = q;
}
else
{
//将新结点的next指向栈顶指示器top所指向的结点
q.Next = top;
//将栈顶指示器top指向新结点
top = q;
}
++size;
}
//出栈操作
public T Pop()
{
if (IsEmpty())
{
Console.WriteLine("Stack is empty !");
return default(T);
}
LinkStackNode<T> p = top;
top = top.Next;
--size;
return p.Data;
}
//获取栈顶结点的值
public T GetTop()
{
if (IsEmpty())
{
Console.WriteLine("Stack is empty !");
return default(T);
}
return top.Data;
}
}
这里没有贴出测试代码!我将会把所有类型的基本实现写完之后,会利用这些结构编写一些经典算法来实战。