抽象数据类型(ADT)

2023-10-11 21:19:43 浏览数 (2)

之前我们在数据结构的时候,自写了栈,当然用链表和数组都写过

栈的实现(数组)

概述栈就不多做介绍了,之前我们讲的很多东西都涉及到了栈。我这里就说一下,如何通过数组和链表实现一个栈。数组大家肯定...

我们既然是学C ,对于抽象数据类型,使用类是一种非常好的方式。

首先描述栈需要执行哪些操作:

创建空栈

push

pop

栈是否满

栈是否为空

可以将上述描述转换为一个声明,其中共有函数表示操作的接口,而私有数据成员负责存储栈数据;

私有数据必须表明数据存储的方式,共有接口应隐藏数据表示,而以通用的术语来表达,如创建栈 压入等。

代码语言:javascript复制
//stack.h
#ifndef _STACK_
#define _STACK_
typedef unsigned long Item;
class Stack
{
private:
enum {MAX = 10};
Item items[MAX];
int top;
public:
  Stack();
  ~Stack();
  bool isempty()const;
  bool isfull()const;
  bool push(const Item& item);
  bool pop(Item& item);

};
#endif // !_STACK_

这里的Item itemsMAX;是栈空间,top是我们栈顶的索引,如果top是0的话则表示栈为空,如果栈是max-1则表示堆栈已满。其他成员函数我们之前在C语言已经做过笔记,感兴趣的可以自己去看一下。

typedef unsigned long Item;我们用item创建无符号长整数 且这个栈存放的是无符号长整数数据的栈

接下来我们来实现方法:

代码语言:javascript复制
#include"stack.h"
Stack::Stack()
{
  top = 0;
}

bool Stack::isempty() const
{
  return top == 0;
}

bool Stack::isfull() const
{
  return top == MAX;
}

bool Stack::push(const Item& item)
{
  if (top<MAX)
  {
      items[top  ] = item;
      return true;
  }
  else
  {
      return false;
  }
  

}

bool Stack::pop(Item& item)
{
  if (top>0)
  {
      item = items[--top];
  }
  else
  {
      return false;
  }

}

之前看过C语言实现堆栈应该不陌生吧,top表示栈顶指针,判断栈是否为空(isempty())只需要判断栈顶是否为0 如果栈满了就是等于数组最大索引(isfull)

push将top作为索引自增同时赋值给数组空间(push),pop将top作为索引自减同时赋值给数组空间。

这里解释一下为什么前面用的是top 后面是--top为什么top-- 不行;

首先分析代码

代码语言:javascript复制
push(12)//top  单拎出来表示top 1,但如果搭配其他变量或者表达式,top  表示先赋值
再自加 所以 items[top  ] = item 表示items[top] = items; 然后top= 1 那么当我们压到第九个时候 top = 10 而top--则是先减后赋值这样就是表示items[top-1] = items;

很好理解

接下来我们再来看看实现代码:

代码语言:javascript复制
#include<iostream>
#include"stack.h"
int main()
{
  using namespace std;
  Stack st;
  char ch;
  unsigned long po;
  cout << "输入a即可入库"
      << "p可以出库 q是退出的意思";
      while (cin>>ch&&toupper(ch)!='Q')
      {
          while (cin.get()!='n')
          {
              continue;
          }
          if (!isalpha(ch))//判断是否字符
          {
              cout << 'a';
              continue;
          }
          switch (ch)
          {
          case 'A':
          case 'a':cout << "请输入数字";
              cin >> po;
              if (st.isfull())
              {
                  cout << "栈已满n";
              }
              else
              {
                  st.push(po);
              }
              break;
          case 'p':
          case 'P':if (st.isempty())
          {
              cout << "栈还是空的n";
          }
                  else
          {
              st.pop(po);
              cout << "PO  #" << po << " poppedn";
          }
                  break;
          }
      }
      cout << "Byen";
      return 0;

}

大致原理是输入a 即压栈 p 即出栈 q 即退出程序

总结

面向对象编程强调的是程序如何表示数据,根据OOP与程序之间的接口来描述数据,从而指定如何使用数据,然后设计一个类来实现该接口,一般来说,私有数据成员存储信息,公有成员函数提供访问数据的唯一途径,类将数据和方法组合成一个单元。

类声明应放在头文件中,定义函数的源代码放在方法文件中。将接口描述和实现细节分开,从理论上说,只需知道公有接口就可以使用类。类是用户定义的类型,对象是类的实例。C 试图让用户定义的类型尽可能与标准类型类似,因此可以声明对象 指向对象的直至真和对象数组 。可以按值传递对象 将对象作为函数返回值 将一个对象赋给同类型的另一个对象。

每个对象都存储自己的数据,而共享类方法。如果mr_object是对象名,try_me是成员函数 则可以 mr_object.try_me调用。

如果需要成员函数对多个对象进行操作,可以将额外的对象作为参数传递给它,如果方法需要显示地调用它的对象,可以使用this指针。由于this指针被设置为调用对象的地址,因此*this是给对象的别名。

0 人点赞