不知不觉大三已至,作为一个朝GPU设计方向行走的微电子屌丝一枚,不禁觉得此领域的水之深。玩玩硬件之余,想起荒废一年的CPP,开始看所谓代码基石的数据结构,跟着大二上了一节课,发现果真大二玩的真开心,所有知识忘得一干二净,于是有了这个学习笔记,督促自己写完老师所讲的内容,再次也希望各路大神能指出内容中的瑕疵之处。
P.S 以下内容以《数据结构与算法分析(C++版)》Clifford A.Shaffer为教材参考数据结构笔记——线性表之顺序表
线性表是由称为元素的数据项组成的一种有限且有序的序列,表示方法为<a0,a1,a2,a3.....>,在以后的代码测试中"<>"为线性表的输出格式。
以下是线性表抽象类声明头文件
#ifndef ACCTLIST_H_
#define ACCTLIST_H_
#include<iostream>
#include<string>
template<class Elem>
class List
{
public:
virtual void clear() = 0;
virtual bool insert(const Elem&) = 0;
virtual bool append(const Elem&) = 0;
virtual bool remove(Elem&) = 0;
virtual void setStart() = 0;
virtual void setEnd() = 0;
virtual void prev() = 0;
virtual void next() = 0;
virtual int leftLength() const = 0;
virtual int rightLength() const = 0;
virtual bool setPos(int pos) = 0;
virtual bool getValue(Elem&) const = 0;
virtual void print() const = 0;
};
#endif
按理说,按照书上的教程,继承类声明应该放在该头文件,再在另外的文件中实现它们,不过因为是测试之前写过的一堆代码,所以没有按照相关的规定书写代码,在后续对CPP的深入了解之后会再做修改。
基于以上原因,我图方便就将继承类写到了另外的头文件中,而且写了很多内联函数,同理,有时间我将修改相关代码。
顺序表头文件
#ifndef LIST_ARRAY_H_
#define LIST_ARRAY_H_
#include<iostream>
#include"acctlist.h"
#include"stack_array.h"
using namespace std;
template<class Elem>
class AList : public List<Elem>
{
private:
int maxSize;
int listSize;
int fence;
Elem* listArray;
public:
AList(int size )
{
maxSize = size;
listSize = fence = 0;
listArray = new Elem[maxSize];
}
~AList()
{
delete [] listArray;
}
void clear()
{
delete [] listArray;
listSize = fence = 0;
listArray = new Elem[maxSize];
}
bool insert(const Elem & item)
{
if(listSize == maxSize)
return false;
for(int i = listSize; i > fence; i--)
listArray[i] = listArray[i-1];
listArray[fence] = item;
listSize++;
return true;
}
bool append(const Elem&item)
{
if(listSize == maxSize)
return false;
listArray[listSize++] = item;
return true;
}
int rightLength() const
{
return listSize - fence;
}
int leftLength() const
{
return fence;
}
bool remove(Elem&it)
{
if(rightLength() == 0)
return false;
it = listArray[fence];//save the item you remove
for(int i = fence; i<listSize - 1; i++)
listArray[i] = listArray[i+1];
listSize--;
return true;
}
void setStart()
{
fence = 0;
}
void setEnd()
{
fence = listSize;
}
void prev()
{
if(fence != 0)
fence--;
}
void next()
{
if(fence < listSize)
fence++;
}
bool setPos(int pos)
{
if( (pos >= 0) && (pos <= listSize))
fence = pos;
return (pos >= 0) && (pos <= listSize);
}
bool getValue(Elem & it) const
{
if(rightLength() == 0)
return false;
else
it = listArray[fence];
return true;
}
bool reverse() const
{
if(listSize == 0)
return false;
AStack<Elem> tempArray(listSize);
for(int i = 0;i < listSize;i++)
{
tempArray.push(listArray[i]);
}
for(int i = 0;i < listSize;i++)
{
tempArray.pop(listArray[i]);
}
return true;
}
void print() const
{
int temp = 0;
cout<<" < ";
while(temp<fence)
cout<<listArray[temp++] <<" ";
cout<<" | ";
while(temp<listSize)
cout<<listArray[temp++] <<" ";
cout<<" >\n LISTSIZE IS "<<listSize<<endl;
cout<<fence<<endl;
}
};
#endif
大家看到我在这个文件的头文件里包含了一个实现数组栈的头文件,加入这个头文件的意义在于实现一个线性表倒序反转的问题,当然先前考虑过不使用这个数组栈的实现,不过粗略想了一下可能不太划算,不过我会再想想是否还有方法。
测试代码
#include<iostream>
//数组的顺序表测试
#include"list_array.h"
using namespace std;
enum{clear,insert,append,rightLength,leftLength,Remove1
,setStart,setEnd,next,prev,setpos,reverse}
;
int main()
{
AList<int> AL(10);
int op;
int temp = 0;
cout<<"Please enter the op code:";
cin >> op;
while( op != 12 )
{
switch(op)
{
case clear:AL.clear();
break;
case insert:cout<<"Please enter the number you want to insert:";
cin>>temp;
AL.insert(temp);
AL.print();
cout<<endl;
break;
case append:cout<<"Please enter the number you want to append:";
cin>>temp;
AL.append(temp);
AL.print();
cout<<endl;
break;
case rightLength:cout<<"the rightlength is "<<AL.rightLength();
cout<<endl;
break;
case leftLength:cout<<"the leftlength is "<<AL.leftLength();
cout<<endl;
break;
case Remove1:cout<<"enter the number you want to remove:";
AL.remove(temp);
AL.print();
cout<<endl;
break;
case setStart:AL.setStart();
cout<<"Now fence at the start";
AL.print();
cout<<endl;
break;
case setEnd:AL.setEnd();
cout<<"Now fence at the end";
AL.print();
cout<<endl;
break;
case next:AL.next();
cout<<"fence at the next";
AL.print();
cout<<endl;
break;
case prev:AL.prev();
cout<<"fence at the prev";
AL.print();
cout<<endl;
break;
case setpos:cout<<"Please enter the setPos:";
cin>>temp;
AL.setPos(temp);
AL.print();
cout<<endl;
break;
case reverse:cout<<"Now reverse the list"<<endl;
AL.reverse();
AL.print();
cout<<endl;
break;
}
cout<<"Please enter the op code:";
cin >> op;
}
cout<<"thanks for using the system";
return 0;
}
先前写这个switch_case语句的时候,觉着将命令直接写成1,2,3,4过于生硬,结果多此一举写了一个枚举变量,到头来还是一会儿事儿,不过方便了代码的阅读,测试代码的简化,需要再思考下是否有更人性化的表示
大家可以看到我的代码略乱,一方面自己还不熟悉CSDN的代码显示功能,另一方面自己的代码风格并未成行,最近在看DOOM3的源代码,很干净简洁,希望大家有时间可以去看看。