您的位置:首页 > 其它

栈模板

2015-07-21 16:36 387 查看
#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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: