C++实现链式栈,运用模板,界面友好,操作方便,运行流畅

//.h文件 

#ifndef STACK_H
 #define STACK_H 

#include<iostream>
 #include<iomanip>
 using namespace std; 

template<typename T>        //链式栈结点
struct L_Node
 {
  T data;
  L_Node<T>* next;
  L_Node();
  L_Node(const T&item,L_Node<T>* next=NULL);                //重载构造函数
}; 

template<typename T>        //链式栈类
class L_Stack
 {
 private:
  L_Node<T>* top;
  int size;
 public:
  L_Stack();
  ~L_Stack();
  void Operation();
 private:
  bool Clear();
  bool Creat();
  bool Pop(T& item);
  void ShowAll();
 }; 

template<typename T>           //结点构造函数
L_Node<T>::L_Node()
 {
  next = NULL;
 } 

template<typename T>           //结点构造函数重载
L_Node<T>::L_Node(const T& item, L_Node<T>* nextnode = NULL)
 {
  data = item;
  next = nextnode;
 }
 template<typename T>           //类的构造函数
L_Stack<T>::L_Stack()
 {
  top = NULL;
  size = 0;
 } 

template<typename T>            //析构函数
L_Stack<T>::~L_Stack()
 {
  if (top) Clear();
 } 

template<typename T>           //创建堆栈
bool L_Stack<T>::Creat()
 {
  top = new L_Node<T>;
  if (top == NULL){ cout << "创建失败!" << endl; return false; }
  size = 0;
  return true;
 } 

template<typename T>            //销毁堆栈
bool L_Stack<T>::Clear()
 {
  if (top == NULL){ cout << "栈未建立或已被销毁,无需再清!" << endl; return false; }
  L_Node<T>* temp;
  while (top != NULL)
  {
   temp = top->next;
   delete top;
   top = temp;
  }
  size = 0;
  return true;
 } 

template<typename T>           //弹出栈顶数据
bool L_Stack<T>::Pop(T& item)
 {
  if (!top){ cout << "栈还未创建或已被销毁,无法进行弹栈操作,请您先创建堆栈并压入数据!" << endl; return false; }
  if (!size){ cout << "栈内数据已全部弹出,无法进行弹栈操作,请您先压入数据!" << endl; return false; }
  //if (top==NULL||size==0){ cout << "栈还未创建或已被销毁,或数据已全部弹出,无法进行弹栈操作,请您先创建堆栈!" << endl; return false; }
  item = top->data;
  L_Node<T>* p = top;
  top = top->next;
  p->next = NULL;
  delete p;             //是否有必要?
 size--;
  return true;
 } 

template<typename T>               //显示所有数据
void L_Stack<T>::ShowAll()
 {
  L_Node<T>* p=top;
  int count ;
  cout << "栈顶→";
  for (count = 1; count <= size; count++, p = p->next)
  {
   if (count == size)cout << p->data;
   else cout <<setw(10)<< p->data << "←→";
   if (count % 5 == 0&&count!=5){cout << endl; cout << "      "; }
  }
  cout << "←栈底" << endl;
 }
 template<typename T>             //封装操作
void L_Stack<T>::Operation()
 {
  bool flager = true;
  while (flager)
  {
   cout << "请您选择操作(输入操作前的数字进行选择):" << endl;
   cout << "1.创建堆栈" << endl;
   cout << "2.批量压入数据" << endl;
   cout << "3.随机压入数据" << endl;
   cout << "4.销毁堆栈" << endl;
   cout << "5.弹出栈顶数据" << endl;
   cout << "6.显示所有数据" << endl;
   cout << "7.显示当前栈内数据个数" << endl;
   int choice;
   cin >> choice;
   switch (choice)
   {
      //由用户创建堆栈
  case 1:
   {
       if (top){ cout << "栈已创建,不能再创建!您可以销毁旧栈后再创建新栈。" << endl; break; }     //先检测栈是否已创建
      bool flag1;
       //创建堆栈
      cout << "正在创建堆栈,请等待……" << endl;
       flag1 = Creat();
       if (flag1){ cout << "堆栈创建成功!" << endl; }
      break;
   }
   //批量压入数据
  case 2:
   {
       int arrsize;   bool flag2 = true;
       if (!top){ cout << "栈还未创建或已被销毁,无法进行压栈操作,请您先创建堆栈!" << endl; break; }//判断是否有栈
       //用户指定压入数据的个数,确保输入的是正整数
      while (flag2)
       {
        cout << "请您输入欲压入数据的个数(注意:只能输入正整数,若您输入其它非法字符,后果自负!):" << endl;
        cin >> arrsize;
        if (arrsize <= 0)
        {
         cout << "请输入正整数!重新输入请按1,退出请按0:" << endl;
         int flagnow;
         cin >> flagnow;
         if (flagnow == 0)goto mark2;
         else flag2 = false;
        }
        if (flag2)flag2 = false;
        else flag2 = true;
       }
       //压入
      T* arr = new T[arrsize];
       cout << "请您输入要压入的数据:" << endl;
       cout << "注意:您输入的数据类型及个数应与您之前指定的一致,否则,造成的一切后果,将由您个人承担,程序开发者概不负责!" << endl;
       for (int i = 0; i < arrsize; i++) cin >> arr[i];
       cout << "正在压入数据,请稍后……" << endl;
       int i;
       for (i = 0; i < arrsize; i++)
       {
        top = new L_Node<T>(arr[i], top);
         size++;
        if (!top)
        {
         cout << "压入数据失败!" << endl;
         cout << "此次新压入数据" << i << "个。" << endl;
         cout << "目前栈内总数据" << size-1 << "个。" << endl;
         goto mark2;
        }
       }
       cout << "数据已成功压入!" << endl;
       cout << "此次新压入数据" << i << "个。" << endl;
       cout << "目前栈内总数据" << size << "个。" << endl;
      mark2:break;
   }
   //随机压入数据
  case 3:
   {
       if (!top){ cout << "栈还未创建或已被销毁,无法进行压栈操作,请您先创建堆栈!" << endl; break; }//判断是否有栈
       cout << "注意:您输入的数据类型应与您之前指定的一致,否则,造成的一切后果,将由您个人承担,程序开发者概不负责!" << endl;
       bool flag3 = true;   int choice3;
       while (flag3)
       {
        T itemer;
        cout << "请输入您的数据(注意:只能输入一个数据,如果您输入多个,后果自负!)" << endl;
        cin >> itemer;
        top = new L_Node<T>(itemer, top);
        if (!top){ cout << "压入数据失败!" << endl; goto mark3; }
        if (top)
        {
         size++;
         cout << "压入数据成功!" << endl;
         cout << "目前栈内总数据" << size << "个。" << endl;
         cout << "是否继续压入?继续请按1,否则请按0:" << endl;
         cin >> choice3;
        }
        if (choice3 == 0)flag3 = false;
       }
      mark3:break;
   }
   //清空堆栈
  case 4:
   {
       bool flag4 = false;
       cout << "您确定要销毁栈?确定请按1,取消请按0:" << endl;
       int choice4;
       cin >> choice4;
       if (choice4 == 1)flag4 = Clear();
       if (flag4) cout << "栈已销毁!" << endl;
       break;
   }
   //弹出栈顶数据
  case 5:
   {
       bool flager=true, flag5; T topdata; int choice5;
       while (flager)
       {
        flag5 = Pop(topdata);
        if (!flag5)goto mark5;
        if (flag5)
        {
         cout << "栈顶数据已成功弹出!" << endl;
         cout << "目前栈内总数据" << size << "个。" << endl;
         cout << "是否输出弹出的数据?是请按1,否则请按0:" << endl;
         cin >> choice5;
         if (choice5 == 1)cout << "弹出的栈顶数据为:" << topdata << endl;
        }
        cout << "是否继续弹出?继续请按1,否则请按0:" << endl;
        cin >> choice5;
        if (choice5 == 0)flager = false;
       }
      mark5: break;
   }
   //显示所有数据
  case 6:
   {
       if (!top){ cout << "栈还未创建或已被销毁,无法显示数据,请您先创建堆栈并压入数据!" << endl; break; }
       if (!size){ cout << "栈内数据已全部弹出,无法显示数据,请您先压入数据!" << endl; break; }
       //if (!top||size==0){ cout << "栈还未创建或已被销毁,或数据已全部弹出,无法显示数据,请您先创建堆栈或压入数据!" << endl; break; }
       cout << "目前栈内共有元素" <<size<<"个:"<< endl;
       ShowAll();
       break; 

  }
     //显示当前栈内数据个数
  case 7:
   {
       if (!top){ cout << "栈还未创建或已被销毁,无法显示数据个数,请您先创建堆栈并压入数据!" << endl; break; }
       if (!size){ cout << "栈内数据已全部弹出,无法显示数据个数,请您先压入数据!" << endl; break; }
       cout << "目前栈内共有元素" << size << "个。" << endl;
       break;
   }
    //处理用户的错误输入
   default:
   {
        cout << "您的输入有误,无法进行操作!" << endl;
        break;
   } 

  }//switch结束
  //控制循环
  cout << "是否继续?继续请按1,退出请按0:" << endl;
   int ifgoon;
   cin >> ifgoon;
   if (ifgoon == 0)flager = false;
  }//while结束
}
 #endif 

//.cpp文件 

#include"stack.h"
 #include<iostream>
 //#include<iomanip>
 using namespace std;
 int main()
 {
  //是否进入程序
 int flagall;   bool flag = true;
  cout << "敬告;请您务必按提示要求操作,如果您进行了规定以外的操作,由此造成的一切后果,将全部由您个人承担,程序开发者概不负责!" << endl;
  cout << "是否进入程序?进入请按1,否则按0;" << endl;
  cin >> flagall;
  if (flagall == 0) return 0;
  //用户选择类型
 while (flag)
  {
   cout << "请选择您所要创建堆栈的数据类型,输入类型前的数字进行选择;" << endl;
   cout << "1.整型  2.浮点  3.字符" << endl;
   cin >> flagall;
   if (flagall != 1 && flagall != 2 && flagall != 3)
   {
    cout << "您的输入有误!重新输入请按1,退出请按0:" << endl;
    cin >> flagall;
    if (flagall == 0)return 0;
    else  flag = false;
   }
   if (flag) flag = false;
   else flag = true;
  }
  switch (flagall)
  {
  case 1:
  {
      L_Stack<int> stack_int;
      stack_int.Operation();
      break;
  }
  case 2:
  {
      L_Stack<float> stack_float;
      stack_float.Operation();
      break;
  }
  case 3:
  {
      L_Stack<char> stack_float;
      stack_float.Operation();
      break;
  }
  default:
   cout << "您的输入有误!" << endl;
   break;
  }
  return 0;
 } 

代码已经过测试,在VS2013上成功运行! 

发此文有两大目的: 

1.和大家交流经验,供需要的人参考。 

2.在下菜鸟,代码中难免有不妥之处,恳求大神批评指正。您的批评就是在下提高的起点,对于您的批评,在下将不胜感激! 
时间: 2024-11-06 21:56:15

C++实现链式栈,运用模板,界面友好,操作方便,运行流畅的相关文章

C++实现二叉树,运用模板,界面友好,操作方便 运行流畅

//.h文件 #ifndef TREE_H #define TREE_H #include<iostream> #include<iomanip> using namespace std; template<typename T> struct Node //树结点 { T data; Node<T> *left, *right; Node(const T& item); }; template<typename T> Node<T

使用模板元编程操作类型集合(C++11下的TypeList)

Wrote by mutouyun. (http://darkc.at/cxx-type-list/) 群里有个朋友要实现这么一个功能:如何在编译期把一个函数类型的参数减少一个. 简单来说,就是实现下面这个模板: remove_func_par<2, void(int, long, short)>::type; // type = void(int, long) 根据输入的编译期整数,把函数参数表里对应的参数干掉一个. 为了实现这种功能,我们需要操作变参模板的参数包.比如像这样: // mak

Rattle:数据挖掘的界面化操作

R语言是一个自由.免费.源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具.这里的统计计算可以是数据分析.建模或是数据挖掘等,通过无数大牛提供的软件包,可以帮我们轻松实现算法的实施. 一些读者觉得R语言零碎的东西太多了,无法记住那么多函数和功能,于是就问R语言有没有一种类似于SAS之EM或SPSS之Modeler的界面化操作.很幸运,Graham等人特地为"偷懒"的分析师写了rattle包,通过该包就可以实现界面化操作的数据分析.数据挖掘流程.下面就跟大家详细介绍一些这款免费的

Hyperledger-fabric 手动操作第一次运行简单网络

Hyperledger-fabric 手动操作第一次运行简单网络 尽量使用fabric-sample/first-network目录中的yaml文件进行配置,第一次自己写配置文件问题很多都不知道怎么解决 创建一个文件夹存放命令执行过程中生成的相关文件 mkdir mynetwork # 创建存放证书的文件夹 cd mynetwork # 使用模板生成证书 cryptogen showtemplate > crypto-config.yaml #修改yaml文件中的内容使符合业务需求 crypto

hadoop学习;hdfs操作;运行抛出权限异常: Permission denied;api查看源码方法;源码不停的向里循环;抽象类通过debug查找源码

eclipse快捷键alt+shift+m将选中的代码封装成方法:alt+shift+l将选中的代码添加对应类型放回参数 当调用一个陌生方法时,进入源码不停的向里循环,当找不到return类似方法的时候,可以看到最原始的方法 package com.kane.hdfs; import java.io.InputStream; import java.net.URL; import org.apache.hadoop.fs.FsUrlStreamHandlerFactory; import org

解决linux/Ubuntu下Qt creater 界面程序在编译运行后无法显示中文或中文乱码问题!

本文解决的主要是界面程序编译运行后无法显示中文的问题,如果在creater 中无法输入中文,下载个IBus或者搜狗之类的中文输入法即可解决! 首先说乱码问题,这个很好解决: 如果是在linux下打开Windows下的项目出现乱码,选择编码为"GB2312"即可! 现在主要来说说程序运行后无法显示中文或者出现乱码的情况,被这个问题困扰了很久,网上看了很多资料贴子都没有解决,所有该添加的都添加了都没办法, http://bbs.csdn.net/topics/390610841?page=

C++实现树的基本操作,界面友好,操作方便,运行流畅,运用模板

Ⅰ.说明: 1.采用左孩子右兄弟的方式,转化为二叉树来实现. 2.树的后根遍历与二叉树的中根遍历即有联系又有区别,请读者注意分析体会. Ⅱ.功能: 1.创建树并写入数据 2.先根遍历树 3.计算树高 4.后根遍历树 5.层次遍历树 6.搜索数据域为某值的结点 7.删除数据域为某值的结点及其子树 8.销毁树 Ⅲ.代码: //.h文件 #ifndef TREE_H #define TREE_H #include<iostream> #include<iomanip> using nam

C++,利用链式栈实现括号匹配,界面友好,操作方便,运行流畅

#include<iostream> #include<string> using namespace std; struct Node { char ch; Node* next; Node(char c, Node* p){ ch = c; next = p; } }; void main() { string str; bool flag = true; while (flag) { cout << "请输入算术表达式:" << e

C++实现有向权图的基本操作,界面友好,操作方便,运行流畅

Ⅰ.功能: 1.创建图 2.展示全图 3.添加顶点 4.添加边 5.删除顶点 6.删除边 7.查看指定边权值 8.修改指定边权值 9.输出两点间的所有简单路及路径对应权值 10.销毁图 ps:关于9,如果不存在任何简单路,输出“不存在任何简单路”.简单路:不含重复顶点的路.如 1 2 3 4 5是简单路,1 2 3 1 4 5不是简单路.可以想见,对于大多数问题,非简单路是没有 研究意义的.如从北京到上海的路线,多次经过同一地点的路线是没有研究价值的. Ⅱ.不足: 1.代码冗长,复用率低.原因是