现在的位置: 首页 > 编程语言 > 正文

C++通用栈代码

2019年04月19日 编程语言 ⁄ 共 4390字 ⁄ 字号 评论关闭

先贴出代码:

#include"stdafx.h"

template <class T>
class STACK
{
public:
	void operator--(int)
	{
		index--;
	}
	void operator-(long count)
	{
		index-=count;
	}
	void operator+(T value)
	{
		Push(value);
	}
	long operator+=(T value)
	{
		return PushDifferent(value);
	}
	T&operator[](long addr)
	{
		if(addr<0)return data[index+1+addr];
		return data[addr];
	}
public:
	STACK()
	{
		basicLen=BASICLEN;
		len=0;
		data=NULL;
		index=-1;
	}
	STACK(long basiclen)
	{
		basicLen=basiclen;
		len=0;
		data=NULL;
		index=-1;
	}
	STACK(T initValue,long count)
	{
		this->basicLen=BASICLEN;
		this->len=0;
		index=-1;
		data=NULL;
		for(long i=0;i<count;i++)Push(initValue);
	}
	~STACK()
	{

	}
	
	void Push(T value)
	{
		index++;
		Extern();
		data[index]=value;
	}
	long PushDifferent(T value)
	{
		for(long i=0;i<=index;i++)if(data[i]==value)return i;//如果T是类,需要重载==。T不能是结构体。
		Push(value);
		return -1;
	}
	void Pop()
	{
		index--;
	}
	void Pop(long count)
	{
		index-=count;
	}
	T Peek()
	{
		return data[index];
	}
	T Peek(long index)
	{
		return data[index];
	}
	void Set(T value)
	{
		data[index]=value;
	}
	void Set(long index,T value)
	{
		data[index]=value;
	}
	void Reset()
	{
		index=-1;
	}
	long Index()
	{
		return index;
	}
	long Id(T value)
	{
		for(long i=0;i<=index;i++)if(value==data[i])return i;
		return -1;
	}
	void SortMinToMax()
	{
		SortLong(data,index+1);
	}
	
private:
	void SortLong(T*set,long count)
	{
		long i=0,j=count-1;
		long val=set[0];
		if(count<2)return;
		while (i<j)
		{
			for(;j>i;j--)if(set[j]<val){set[i]=set[j];break;}
			for(;i<j;i++)if(set[i]>val){set[j]=set[i];break;}
		}
		set[i]=val;
		SortLong(set,i);
		SortLong(set+i+1,count-i-1);
	}
	void Extern()
	{
		if(index<len)return;
		T*tmp=new T[len+=basicLen];
		for(long i=0;i<index;i++)
			tmp[i]=data[i];
		if(data)delete[]data;
		data=tmp;
	}

private:
	T*data;
private:
	long index,len,basicLen;
	static const long BASICLEN=5;
};

这是我最近做编译器时自己创建的一个功能比较多的C++栈代码,使用了模板类来作为栈的数据类型,所以理论上支持很多的数据类型,比如long,int,bool,char,char*.也支持用户自定义的类(但请不要使用结构类型,否则可能会出错)类型。
同时,为了便于栈的操作,在里面重载了一些运算符。我把这个栈的功能写在下面便于大家参考:
0.初始化:(1)STACK():正常的初始化;默认的基本块长度为5.
         (2)STACK(long b):初始化时把栈的基本块长度设为b.b应为正整数。这个初始化函数与第一个作用一样,提供这个函数是为了让用户在程序执行速度与内存开销间作一个合理的选择。
         (3)STACK(T iv,long c):初始化后在栈中写入c个值为iv的数据。
1.入栈:(1)Push(T v)或+v:把数据v写入栈顶。无返回值;
       (2)PushDifferent(T v)或+=v:如果在栈里面没有v这个数据,则把v写入栈顶,返回值为-1;否则返回v在栈中的索引。(如果数据类型不是可比较大小的,则需要在那个数据类中重载==运算符(返回类型应为bool型),否则会出错)
2.出栈:(1)Pop()或--:去掉处于栈顶的数据;
       (2)Pop(long c)或-c:去掉自栈顶向下的c个数据;
3.读栈:(1)Peek():读出栈顶数据;
       (2)Peek(long i):读出栈中索引为i的数据;
       (3)[i]:若i为非负数,返回栈中data[i]的引用,若i为负数,返回data[index+i+1]的引用。
4.置栈:(1)Set(T v)更改栈顶的数据为v;
       (2)Set(long i,T v)更改栈中索引为i处的数据为v;
5.读当前索引:Index():返回当前的索引值.栈底的索引为0,以此往上推。
6.重置栈:Reset():重置栈索引为-1,也就是清空栈(实际数据还在,只是栈索引没有指向其中的数据了)。
7.读取数据索引:Id(T v):如果栈中有数据v,返回v的索引;否则返回-1(表示没有v)。
8.从小到大排序:SortMinToMax():把栈中的数据按从小到大的顺序排列,这会改变栈中的数据。如果数据类型不是可比较大小的,则需要在那个数据类中重载<,>(返回类型应为bool型)这两个运算符,否则会出错。
9.私有函数说明:Extern():这个函数是当索引指针超过data的数据个数len时增大data的数据个数。在Push(T v)、PushDifferent(T v)和STACK(T iv,long c)中都会调用该函数以自动增大data的大小。

应用例子:
0.初始化:(1)STACK stack;//声明了一个栈,名字为stack。
         (2)STACK stack=STACK(2);//声明了一个栈stack,这个栈的基本数据个数为2。
         (3)STACK stack=STACK("fvck",8);//声明了一个栈stack,并入其中写入了8个"fvck"。

1.入栈:
STACK st;
(1)st.Push('a');//把a置入栈中
(2)st+'a';//同上
(3)st.PushDifferent('a');//若栈中没有'a',把'a'置入栈中
(4)st+='a';//同上

2.出栈:假设栈st中有数据2,3,1,4,7
(1)st.Pop();//数据变为2,3,1,4
(2)st--;//同上
(3)st.Pop(2);//数据变为2,3,1
(4)st-2;//同上

3.读栈:假设栈st中有数据2,5,3,4
(1)a=st.Peek();//a的值为4
(2)a=st.Peek(1);//a的值为5
(3)a.st.Peek(0);//工的值为2

(3)a=st[1];//a的值为5
(4)a=st[-1];//a的值为4
(5)a=st[-3];//工的值为5
置栈:
(6)st[0]=8;//栈中数据变为8,5,3,4
(7)st[-2]=9;//栈中数据变为2,5,9,4
从(3)~(7)我们看出可以把栈当成数组来使用,而且这个数组不需要声明大小,但需要使用Push等函数来扩展长度。数组的索引可以为负,当为负时,-1表示栈顶,依次往下数。

4.置栈:假设栈st中有数据4,2,34,5,99
(1)st.Set(8);//栈中数据变为4,2,34,5,8
(2)st.Set(2,8);//栈中数据变为4,2,8,5,99

5.读当前索引:假设栈st中有数据3,4,24,5,9,9,8
long i=st.Index();//i的值为6

6.重置栈:假设栈st中有数据23,4,2
st.Reset();//栈中没有数据了

7.读取数据索引:假设栈st中有数据2,33,4,22,5
(1)long i=st.Id(22);//i的值为3
(2)long i=st.Id(8);//i的值为-1

8.从小到大排序:假设栈st中有数据2,3,44,9,7
st.SortMinToMax();//栈中数据变为2,3,7,9,44
从2~8,为了方便,我们栈中的数据都是整数值,这是明显可以比较大小的数据,那么对于用户自定义的数据,怎么样才能使用PushDifferent与+=呢?例子如下(这是我编译器中的一个类声明代码):

class RANGE
{
public:
	static const unsigned long R_MIN=0,R_MAX=0xffff;
	//全部相等
	bool operator==(RANGE v)
	{
		if(this->left==v.left&&this->right==v.right&&this->flag==v.flag)return true;
		return false;
	}
	bool operator<=(RANGE v)
	{
		if(v.flag==RANGE::WITHIN)
		{
			if(this->left>=v.left&&this->right<=v.right)return true;
		}
		else if(v.flag==RANGE::WITHOUT)
		{
			if(this->left>=R_MIN&&this->right<=v.left)return true;
			if(this->left>=v.right&&this->right<=R_MAX)return true;
		}
		return false;
	}
public:
	RANGE()
	{

	}
	RANGE(long left,long right,int flag)
	{
		this->left=left;
		this->right=right;
		this->flag=flag;
	}
public:
	enum{WITHIN,WITHOUT};
	long left,right;
	int flag;
};

在这个类中,重载了==运算符,而且返回值为bool型,所以RANGE类型的数据可以在PushDifferent与+=中使用。



抱歉!评论已关闭.