- 基于顺序表实现的线性表
- 基于链表实现的线性表
- 实验中遇到的问题(&DevC++中的骚操作)
一、基于顺序表实现的线性表
List.h
#include <iostream>
using namespace std;
#ifndef _List
#define _List
namespace wangzhe
{
template <typename E>
class List
{
private:
void operator =(const List&) {}
List(const List&) {}
public:
List() {}
virtual ~List() {}
virtual void clear() =0;
virtual void insert(const E& item) =0;
virtual void append(const E& item) =0;
virtual E remove() =0;
virtual void moveToStart() =0;
virtual void moveToEnd() =0;
virtual void prev() =0;
virtual void next() =0;
virtual int length() const =0;
virtual int currPos() const =0;
virtual void moveToPos(int pos) =0;
virtual const E& getValue() const =0;
};
}
#endif
AList.h
#include<iostream>
using namespace std;
#include"List.h"
#ifndef _AList
#define _AList
namespace wangzhe
{
template <typename E>
class AList:public List<E>
{
private:
int maxSize;
int listSize;
int curr;
E* listArray;
public:
AList(int size);
~AList();
void clear();
void insert(const E& item);
void append(const E& item);
E remove();
void moveToStart();
void moveToEnd();
void prev();
void next();
int length() const;
int currPos() const;
void moveToPos(int pos) ;
const E& getValue() const ;
};
}
#endif
AList.cpp
#include<iostream>
using namespace std;
#include"AList.h"
namespace wangzhe
{
template <typename E>
AList<E>::AList(int size)
{
maxSize=size;
listSize=curr=0;
listArray =new E[maxSize];
}
template <typename E>
AList<E>::~AList()
{
delete [] listArray;
}
template <typename E>
void AList<E>::clear()
{
delete [] listArray;
listSize=curr=0;
listArray=new E[maxSize];
}
template <typename E>
void AList<E>::insert(const E& item)
{
if(listSize>=maxSize)
{
cout<<"List capacity exceeded"<<endl;
return;
}
for(int i=listSize;i>curr;i--)
{
listArray[i]=listArray[i-1];
}
listArray[curr]=item;
listSize++;
}
template <typename E>
void AList<E>::append(const E& item)
{
if(listSize>=maxSize)
{
cout<<"List capacity exceeded"<<endl;
return;
}
listArray[listSize++]=item;
}
template <typename E>
E AList<E>::remove()
{
if(curr<0||curr>=listSize)
{
cout<<"No element"<<endl;
return 0;
}
E it=listArray[curr];
for(int i=curr;i<listSize-1;i++)
listArray[i]=listArray[i+1];
listSize--;
return it;
}
template <typename E>
void AList<E>::moveToStart()
{
curr=0;
}
template <typename E>
void AList<E>::moveToEnd()
{
curr=listSize;
}
template <typename E>
void AList<E>::prev()
{
if(curr!=0) curr--;
}
template <typename E>
void AList<E>::next()
{
if(curr<listSize) curr++;
}
template <typename E>
int AList<E>::length() const
{
return listSize;
}
template <typename E>
int AList<E>::currPos() const
{
return curr;
}
template <typename E>
void AList<E>::moveToPos(int pos)
{
if(pos<0||pos>=listSize)
{
cout<<"No current element"<<endl;
return;
}
curr=pos;
}
template <typename E>
const E& AList<E>::getValue() const
{
if(curr<0||curr>=listSize)
{
cout<<"No current element"<<endl;
return 0;
}
return listArray[curr];
}
}
main.cpp
#include <iostream>
using namespace std;
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
#include"AList.h"
#include"AList.cpp"
using namespace wangzhe;
int main(int argc, char** argv)
{
for(int i=1;i<=50;i++) cout<<'-';
cout<<"\n"<<"基于顺序表实现的线性表基本操作演示\n";
for(int i=1;i<=50;i++) cout<<'-';
cout<<endl;
AList<int> a(10010);
cout<<"请输入对应的数字实现相关操作:\n";
cout<<" 0、退出操作\n";
cout<<" 1、在当前位置插入一个元素\n";
cout<<" 2、在末尾插入一个元素\n";
cout<<" 3、删除当前位置的元素并输出其值\n";
cout<<" 4、将当前位置置于第一个元素\n";
cout<<" 5、将当前位置置于最后一个元素\n";
cout<<" 6、将当前位置向前移一个\n";
cout<<" 7、将当前位置向后移一个\n";
cout<<" 8、输出当前元素个数\n";
cout<<" 9、输出当前位置\n";
cout<<"10、将当前位置置于给定位置处\n";
cout<<"11、输出当前位置的元素\n";
cout<<"12、输出当前所有元素\n";
cout<<"13、清空所有元素\n";
for(int i=1;i<=50;i++) cout<<'-';
cout<<endl;
int order,temp;
while(1)
{
cin>>order;
if(!order) break;
switch (order)
{
case 1:
{
cout<<"输入要插入的元素:\n";
cin>>temp;
a.insert(temp);
break;
}
case 2:
{
cout<<"输入要插入的元素:\n";
cin>>temp;
a.append(temp);
break;
}
case 3:
{
cout<<a.remove()<<endl;
break;
}
case 4:
{
a.moveToStart();
break;
}
case 5:
{
a.moveToEnd();
break;
}
case 6:
{
a.prev();
break;
}
case 7:
{
a.next();
break;
}
case 8:
{
cout<<a.length()<<endl;
break;
}
case 9:
{
cout<<a.currPos()<<endl;
break;
}
case 10:
{
cout<<"输入给定位置:\n";
cin>>temp;
a.moveToPos(temp);
break;
}
case 11:
{
cout<<a.getValue()<<endl;
break;
}
case 12:
{
for(a.moveToStart();a.currPos()<a.length();a.next())
cout<<a.getValue()<<' ';
cout<<endl;
break;
}
case 13:
{
a.clear();
break;
}
default: break;
}
}
return 0;
}
二、基于链表实现的线性表
List.h
同顺序表
Link.h
#include <iostream>
using namespace std;
#ifndef _Link
#define _Link
namespace wangzhe
{
template<typename E>
class Link
{
public:
E element;
Link *next;
Link(const E& elemval,Link* nextval =NULL)
{
element=elemval;
next=nextval;
}
Link(Link* nextval=NULL)
{
next=nextval;
}
};
}
#endif
LList.h
#include<iostream>
using namespace std;
#include"List.h"
#include"Link.h"
#ifndef _LList
#define _LList
namespace wangzhe
{
template<typename E>
class LList:public List<E>
{
private:
Link<E>* head;
Link<E>* tail;
Link<E>* curr;
int cnt;
void init();
void removeall();
public:
LList(int size);
~LList();
void print() const;
void clear();
void insert(const E& it);
void append(const E& it);
E remove();
void moveToStart();
void moveToEnd();
void prev();
void next();
int length() const;
int currPos() const;
void moveToPos(int pos);
const E& getValue() const;
};
}
#endif
LList.cpp
#include<iostream>
using namespace std;
#include"LList.h"
namespace wangzhe
{
template<typename E>
void LList<E>::init()
{
curr=tail=head=new Link<E>;
head->next=NULL;
cnt=0;
}
template<typename E>
void LList<E>::removeall()
{
while(head!=NULL)
{
curr=head;
head=head->next;
delete curr;
}
}
template<typename E>
LList<E>::LList(int size)
{
init();
}
template<typename E>
LList<E>::~LList()
{
removeall();
}
template<typename E>
void LList<E>::print() const
{
Link<E>* temp=head->next;
while(temp!=NULL)
{
cout<<temp->element<<' ';
temp=temp->next;
}
}
template<typename E>
void LList<E>::clear()
{
removeall();
init();
}
template<typename E>
void LList<E>::insert(const E& it)
{
curr->next=new Link<E>(it,curr->next);
if(tail==curr) tail=curr->next;
cnt++;
}
template<typename E>
void LList<E>::append(const E& it)
{
tail=tail->next=new Link<E>(it,NULL);
cnt++;
}
template<typename E>
E LList<E>::remove()//删除当前指向的下一个结点
{
if(curr->next==NULL)
{
cout<<"No element"<<endl;
return 0;
}
E it=curr->next->element;
Link<E>* temp=curr->next;
if(tail==curr->next) tail=curr;
curr->next=curr->next->next;
delete temp;
cnt--;
return it;
}
template<typename E>
void LList<E>::moveToStart()
{
curr=head;
}
template<typename E>
void LList<E>::moveToEnd()
{
curr=tail;
}
template<typename E>
void LList<E>::prev()
{
if(curr==head)
{
cout<<"curr is the head\n";
return;
}
Link<E>* temp=head;
while(temp->next!=curr) temp=temp->next;
curr=temp;
}
template<typename E>
void LList<E>::next()
{
if(curr==tail)
{
cout<<"curr is the tail\n";
return;
}
curr=curr->next;
}
template<typename E>
int LList<E>::length() const
{
return cnt;
}
template<typename E>
int LList<E>::currPos() const
{
Link<E>* temp=head;
int i;
for(i=0;temp!=curr;i++)
temp=temp->next;
return i;
}
template<typename E>
void LList<E>::moveToPos(int pos)
{
if(pos<0||pos>cnt)
{
cout<<"Position out of tange\n";
}
curr=head;
for(int i=0;i<pos;i++) curr=curr->next;
}
template<typename E>
const E& LList<E>::getValue() const
{
if(curr->next==NULL)
{
cout<<"No value\n";
return -1;
}
return curr->next->element;
}
}
main.cpp
参考顺序表
三、实验中遇到的问题(&DevC++中的骚操作)
1、注意函数声明与定义的区别;
2、有#include"XXX.cpp"的骚操作(类模板的定义和声明是能在.h和.cpp分离的!!,只不过在main.cpp中除了需要包括.h之外还要包括相应的.cpp!!!);
3、某个.h里的构造函数名与类名中的一个字母大小写不同,devC++竟然不报错,着实可恶,因此应该注意大小写。
参考文献
【1】Clifford A.Shaffer.数据结构与算法分析【M】.北京:电子工业出版社,2013:62-68.