《数据结构》读书笔记 第五章 数组的顺序存储实现

昨天读《The C++ Programing Language Special Edition》确实觉得注释是很重要的,所以今天开始所有程序都要练习注释,尽量写出好的注释来:-)

Array.h : 定义了数组的顺序存储的基本操作

#include <iostream>
#include <cstdarg>

typedef int Elem;
typedef int Status;
enum {WRONG=-1,OK=0};

struct Array
{
/*----------------------------------------------
  ★Array的数据结构说明★
  -----------------------
 dim 存储数组的维数
 bounds  bounds[i]表示第i维有多少个该维元素
 consist consist[i]表示第i层有多少个一维元素
-----------------------------------------------*/
 Elem *base;
 int dim;
 int *bounds;
 int *consist;
};

Status InitArray(Array &A,int dim,...)
{
/*----------------------------------------------
  ★InitArray函数的说明★
  -----------------------
 作用:按照按照维数,每维的长度来初始化"数组"
 参数:数组A(引用),维数,...(不定个维数,但数量当与维数一致)
 基本算法:(0)设置A的维数
           (1)分配A.bounds并依次填入每个维的长度,计算total元素总数
     (2)根据total(元素总数)分配A.base即存储数据的堆
     (3)分配并填入A.consist即当前维所含的一维元素数(为Locate提供方便)
-----------------------------------------------*/ 

 int i,total=1;
 va_list ap;
 va_start(ap,dim);
 A.dim=dim;
 A.bounds=new int[dim];
 if(A.bounds==NULL)
  return WRONG;
 for(i=0;i<dim;i++)
 {
  A.bounds[i]=va_arg(ap,int);
  if(A.bounds[i]<0)
   return WRONG;
  total*=A.bounds[i];
 }
 va_end(ap);
 A.base=new int[total];
 if(A.base==NULL)
  return WRONG;
 A.consist=new int[dim];
 if(A.consist==NULL)
  return WRONG;
 A.consist[dim-1]=1;
 for(i=dim-2;i>=0;i--)
 {
  A.consist[i]=A.bounds[i+1]*A.consist[i+1];
 }
 return OK;
}

void DestroyArray(Array &A)
{
/*----------------------------------------------
  ★DestroyArray函数说明★
  -----------------------
 作用:销毁"数组"
 参数:数组A(引用)
 基本算法:(0)如果必要,则删除所有分配过的new堆
           (1)把所有的地址置为NULL
     (2)维数设置为0
-----------------------------------------------*/ 
 if(A.base!=NULL)
  delete A.base;
 if(A.bounds!=NULL)
  delete A.bounds;
 if(A.consist!=NULL)
  delete A.consist;
 A.dim=0;
 A.base=A.bounds=A.consist=NULL;
 std::cout<<"数组销毁完成!"<<std::endl;
}

Status Locate(Array A,va_list ap,int &off)
{
/*----------------------------------------------
  ★Locate函数说明★
  -----------------------
 作用:给"数组"某元素定位
 参数:数组A,va_list ap(宏取出的维数列表),off 偏移量(引用)
 基本算法:(0)根据下标由公式计算off
           (1)给off赋值,返回
-----------------------------------------------*/ 
 int i,t;
 off=0;
 for(i=0;i<A.dim;i++)
 {
  t=va_arg(ap,int);
  if(t<0||t>=A.bounds[i])
   return WRONG;
  off+=A.consist[i]*t;
 }
 //std::cout<<"定位"<<off<<std::endl;
 return OK;
}

Status Assign(Array A,Elem e,...)
{
/*----------------------------------------------
  ★Assign函数说明★
  -----------------------
 作用:给"数组"某元素赋值
 参数:数组A(引用),待设置元素之值Elem e,...(不定长度参数,确定不同维的下标)
 基本算法:(0)调用Visit确定下标位置
           (1)设置值
-----------------------------------------------*/ 
 int off;
 va_list ap;
 va_start(ap,e);
 if(Locate(A,ap,off)==WRONG)
  return WRONG;
 *(A.base+off)=e;

 return OK;
}

Elem Visit(Array A,...)
{
/*----------------------------------------------
  ★Visit函数说明★
  -----------------------
 作用:访问"数组"某元素
 参数:数组A,...(不定长度参数,确定不同维的下标)
 基本算法:(0)调用Visit确定下标位置
           (1)返回下标位置处的元素值
-----------------------------------------------*/
 va_list ap;
 int off;
 va_start(ap,A);
 if(Locate(A,ap,off)==WRONG)
  return WRONG;
 
 return A.base[off];
}

main.cpp

#include "Array.h"

using namespace std;
int main()
{
 int i,j,k,tmp;
 Array A;
 if(InitArray(A,3,3,4,2)==OK)
  cout<<"成功初始化数组!"<<endl;
 else
  cout<<"数组初始化失败!"<<endl;
 cout<<"A.bounds  : ";
 for(i=0;i<3;i++)
  cout<<A.bounds[i]<<" ";
 cout<<endl<<"A.consist : ";
 for(i=0;i<3;i++)
  cout<<A.consist[i]<<" ";
 cout<<endl;

 for(i=0;i<3;i++)
  for(j=0;j<4;j++)
   for(k=0;k<2;k++)
    if(Assign(A,i*100+j*10+k,i,j,k)==OK)
     //cout<<"成功赋值!";
     ;

 cout<<"三页四行两列的矩阵输出如下:"<<endl;
 for(i=0;i<3;i++)
  for(j=0;j<4;j++)
   for(k=0;k<2;k++)
   {
    tmp=Visit(A,i,j,k);
    cout.setf(ios::left);
    cout<<"A["<<i<<"]["<<j<<"]["<<k<<"]= ";
    cout.width(3);
    cout<<tmp<<"  ";
    if(k==1)
     cout<<endl;
    if(j==3&&k==1)
     cout<<endl;
   }
 
 cout<<"A.base:"<<endl;
 for(i=0;i<24;i++)
 {
  cout.width(4);
  cout<<A.base[i]<<" ";
  if((i+1)%8==0)
   cout<<endl;
 }

 
 cout<<endl<<"A.dim="<<A.dim<<endl;
 DestroyArray(A);
 return 0;
}

Leave a Reply

Your email address will not be published. Required fields are marked *