栈模板

#include <iostream>
#include <string>
#include <stdio.h>
#include <malloc.h>
#include <string.h>
using namespace std;



class aa
{
public:
	int i;
	aa(){this->i=0;}
	aa(int i)
	{
		this->i=i;
	}
	bool operator==(aa& a1)
	{
		return this->i==a1.i;
	}
};

ostream& operator<<(ostream& out,aa& a1)
{
	out<<a1.i;
	return out;
}
template <class T>
class Stack
{
public:
	Stack() //一般无参的构造函数总会把一些成员指针初始化为0
	{
		this->pHead=0;
		this->pNext=0;
		this->pPre=0;
	}
	Stack(T& s)
	{
		this->m_T=s;
		this->pHead=0;
		this->pNext=0;
		this->pPre=0;
	}
	T m_T;
	Stack* pNext;//记录下一个节点的地址
	Stack* pPre;//记录上一个节点的地址
	Stack* pHead;//把头保存在这个结构体中,相当于原来c语言的全局变量的使用
//	但是比全局变量好,因为是栈变量
	void SearchAll( );
	int Search( T tFind);
	void Pop( );
	void Push( T& tNewStack);
};


template<class T>
void Stack<T>::SearchAll( ) //这个函数是全局函数 ,它不同于位于class Stack 内部的SearchAll这个成员函数
{
	Stack<T>* pStack=this->pHead;
	/*********************************
	如何遍历?应该顺着第一个节点的pNext持续找到下一个,并进行输出,直到遇到pNext==0为止
	**********************************/
	Stack<T>* pHead=pStack;
	if (pStack==NULL) 
	{
		printf("null link table!\n");
		return;
	}
	while(1)
	{
		//原来的c语言的方式已经不能适应c++的模板类输出了
		cout<<pStack->m_T<<endl;
		if (pStack->pNext==pHead) break; //当运行到最后一个结点的时候,将不会打印
		//我们还需要做到的就是顺着pNext不断的改变pStack的位置
		pStack=pStack->pNext;
	}

}
template <class T>
int Stack<T>::Search( T tFind)
{
	Stack<T>* pStack=this->pHead;
	/**********************************/
	/*如果找到某一个节点,则报告它的ID*/
	/*如果没有找到某一个节点,则报告没有找到*/
	/*返回值:
	/*       1 表示成功找到
	/*       -1 表示没有找到
	/**********************************/
	Stack<T>* pHead=pStack;
	while(1)
	{
		if (pStack->m_T==tFind) 
		{
			printf("find this node!\n");
			return 1;
		}
		//我们需要判断的是跳出点
		if (pStack->pNext==pHead) break; //当运行到起始节点的时候跳出
		//我们还需要做到的就是顺着pNext不断的改变pStack的位置
		pStack=pStack->pNext;
	}
	printf("don't find this node!\n");
	return -1;
}

template<class T>
void Stack<T>::Pop( )
{
	 Stack<T>* pStack=this->pHead;
	//找到最后一个节点
	//执行删除操作

	 Stack<T> *pHead=pStack;//把pHead记录下来	
	//特殊处理
	//如何判断只有一个节点	
	if (pStack->pNext==pStack)
	{
		pHead=0;
		free(pStack);
		this->pHead=pHead;
	}

	
	//需要把pStack指向尾巴
	pStack=pHead->pPre;//头指针的pPre就是尾巴

	//1把当前节点的上一个节点指向当前节点的下一个节点
	pStack->pPre->pNext=pStack->pNext;
	//2 把当前节点的下一个节点的pPre指向当前节点的上一个节点
	pStack->pNext->pPre=pStack->pPre;

	free(pStack);//这里的顺序非常重要

	printf("pop stack succeed!\n");
	
	this->pHead=pHead;
}



template<class T>
void Stack<T>::Push( T& tNewStack)
{
	 Stack<T>* pStack=this->pHead;
	//增加在原来的插入的基础上,不需要查找点了,相当于对头节点进行插入
	//只是头指针不要再变化而已
	 Stack<T> *pHead=pStack;//把pHead记录下来
	 Stack<T> *pNew=NULL;//用于创建新的结点位置记录
	char ifFind=0;//表示没有找到

	//特殊处理如下:
	//如果链表是空的,则直接创建新的节点,并把pHead给这个新的节点
	if (pStack==NULL)
	{
		//1 建立新的节点
		pNew=new Stack<T>;

		pNew->m_T=tNewStack;//把原来的具体类型的值修改为T的值
		
		pNew->pNext=pNew;//并把新的节点的pNext置为NULL
		pNew->pPre=pNew;
		pHead=pNew;
		printf("push stack succeed!\n");
		this->pHead=pHead;
		return;
	}
	
	//1 建立新的节点
	pNew=new Stack<T>;

	pNew->m_T=tNewStack;//把原来具体类型的值修改为T的值
	
	pNew->pNext=pNew;//把新的节点的上下指针分别指向自己
	pNew->pPre=pNew;

	//1 把当前节点的上一个的pNext指向新的节点
	pStack->pPre->pNext=pNew;
	//2 把新的节点的pNext指向当前节点
	pNew->pNext=pStack;
	//3 把新的节点的pPre指向当前节点的上一个节点
	pNew->pPre=pStack->pPre;
	//4 把当前节点的pPre指向新的节点
	pStack->pPre=pNew;

	
	printf("push stack succeed!\n");
	this->pHead=pHead;
}

int main(int argc, char* argv[])
{
	//下面就要用这个万能的栈了,泛性栈,模板栈
	Stack<aa> s;
	aa i(1),j(2),k(3);
	s.Push(i);
	s.Push(j);
	s.Push(k);
	s.SearchAll();
	s.Search(j);
	return 0;
}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值