线性表
我们都知道是一种常用的数据结构,也是历来各种考试的重点。今天抽了一些时间把线性表做了总结。
线性表是n个数据元素的一个有限序列。用公式表示为:
L=(a1,a2,a3,a4,...........an)
因为线性表是一个有限的序列,所以也如上面公式所示,它的各个元素是相继排放的。那么它的每个相连的两项之间都是有一个逻辑关系。那就是直接前驱和直接后继的关系。我们说除了第一个表项外,所有表项都有直接前驱。除了最后一个表项外。所有表项都有直接后继。线性表是唯一存在着这种关系的结构。线性表至多拥有一个直接前驱,一个直接后继。这就是线性表的基本特点了。
下面重点说顺序表。
顺序表
我们都知道线性表按照其存储表示不同,分为顺序表和链表。所谓顺序表就是以数组作为存储结构的。(链表后面再说)。那么该如何定义呢??简单来说,顺序表是按其逻辑顺序从指定的位置开始的一块连续存储区域。如果实在不能理解就是可以类比数组。顺序表的各个表项的逻辑顺序与其物理顺序是一致的。也就是说第n个表项存储在第n个物理位置。另外,顺序表最重要的特点就是它是支持顺序访问,也支持随机访问。怎么理解两种访问呢。第一,顺序访问:也就是从第一个表项开始逐次遍历,直到找到目标表项。而随机访问呢。就不言而喻了。就是不需遍历。直接访问元素。一般通过下标来直接确定。非常便捷。时间复杂度是o(1);
刚才说了。顺序表可以用数组来表示。那么原理是什么呢。其实很简单。我们只需申请一块数组空间就行了。要注意数组的大小不能小于表项的个数。顺序表的第一个表项存储在数组的第一个位置,也就是第0的位置。。
依次类推。那么第n个表项就存储在数组的第n-1个地方。书上有个公式比较准确的可以描述:
loc(i)=loc(1)+n-1*sizeof(t);
那么怎样用代码来表示呢。
可以这样来做
typedef struct {
typename data[maxsize];
int n;
}list;
上面的代码是静态存储表示。这个存储是有bug的。如果表项的数量比预设数组的大小要大。那么就会溢出。最好的是设一个动态的存储表示
typedef struct
{
typename *data;
int maxsize;
int n;
}list;
下面给出顺序表的完整实现过程:
#ifndef LINERLIST_H
#define LINERLIST_H
template <typename T>class LinerList{
public:
LinerList();
~LinerList();
virtual int Size() const = 0;
virtual int Length() const = 0;
virtual int Search(T& x) const = 0;
virtual bool getData(int i,T&x) const = 0;
virtual void setData(int i, T& x) = 0;
virtual bool Insert(int i, T& x) = 0;
virtual bool Remove(int i, T& x) = 0;
virtual bool IsEmpty() const = 0;
virtual bool IsFull() const = 0;
virtual void Sort() = 0;
virtual void input() = 0;
virtual void ouput() = 0;
virtual LinerList<T> operator = (LinerList<T>& L) = 0;
};
#endif
#ifndef SEQLIST_H
#define SEQLIST_H
#include <iostream>
#include <cstdlib>
#include <cassert>
using namespace std;
const int defaultSize = 100;
template <typename T>class SeqList{
protected:
T *data;
int maxSize;
int last;
public:
SeqList(int sz = defaultSize);
SeqList(SeqList<T> &L);
~SeqList(){
delete []data;
}
void reSize(int newSize);
int Size() const{
return maxSize;
}
int Length()const{
return last+1;
}
int Search(T &x) const;
int Locate(int i) const;
bool getData(int i,T&x) const{//改
if(i>0 && i<=last+1){
x=data[i-1];
return true;
}
else return false;
}
void setData(int i, T &x){
if (i>0 && i<=last+1){
data[i-1] = x;
}
}
bool Insert(int i, T &x);
bool Remove(int i, T &x);
bool IsEmpty(){
return (last == -1);
}
bool IsFull(){
return (last == maxSize-1);
}
void Sort();
void input();
void output();
SeqList<T> operator = (SeqList<T> &L);
friend istream& operator >> (istream &in, SeqList<T> &R){
R.last = -1;//先清空
while (!in.eof()){
R.last++;
if (R.last == R.maxSize) R.reSize(2*R.maxSize);
assert(in >> R.data[R.last]);
}
return in;
}
friend ostream& operator << (ostream &out, SeqList<T> &R){
for (int i = 0; i <= R.last; i++){
cout << "#" << i+1 << ":\t" << R.data[i] << endl;
}
return out;
}
};
template <typename T>SeqList<T>::SeqList(int sz){
if (sz > 0){
maxSize = sz;
last = -1;
data = new T[maxSize];
if (data == NULL){
cerr << "Memory allocating error!" << endl;
exit(1);
}
}
}
template <typename T>SeqList<T>::SeqList(SeqList<T> &L){
maxSize = L.Size();
last = L.Length() - 1;
data = new T[maxSize];
if (data == NULL){
cerr << "Memory allocating error!" << endl;
exit(1);
}
for (int i = 1; i <= last+1; i++) data[i-1] = *(L.getData(i));
}
template<typename T>void SeqList<T>::reSize(int newSize){
if (newSize <= 0){
cerr << "Invalid array index!" << endl;
return;
}
if (newSize != maxSize){
T *newarray = new T[newSize];
if (newarray == NULL){
cerr << "Memory allocating error!" << endl;
exit(1);
}
int n = last;//改
T *srcptr = data;
T *destptr = newarray;
while (n--) *destptr++ = *srcptr++;
delete []data;
data = newarray;
maxSize = newSize;
}
}
template<typename T>int SeqList<T>::Search(T &x)const{
for (int i = 0; i <= last; i++) {
if (data[i] == x) return i+1;
}
return 0;
}
template<typename T>int SeqList<T>::Locate(int i)const{
if (i >= 1 && i <= last+1) return i;
else return 0;
}
template<typename T>bool SeqList<T>::Insert(int i, T &x){
if (last == maxSize-1) return false;
if (i < 0 || i > last+1) return false;
for (int j = last; j >= i; j--) data[j+1] = data[j];
data[i] = x;
last++;
return true;
}
template<typename T>bool SeqList<T>::Remove(int i, T &x){
if (last == -1) return false;
if (i < 1 || i > last+1) return false;
x = data[i-1];
for (int j = i; j <= last; j++) data[j-1] = data[j];
last--;
return true;
}
template<typename T>void SeqList<T>::Sort(){
for (int i = 1; i <= last; i++){
for (int j = last; j >= i; j--){
if (data[j-1] > data[j]){
T tmp = data[j-1];
data[j-1] = data[j];
data[j] = tmp;
}
}
}
}
template<typename T>void SeqList<T>::input(){
cout << "Input the size of the list which will be created:";
while (1) {
assert(cin >> last);
last--;
if (last < 0){
cout << "Input error, the size must be positive!\n";
cout << "Input the size again:";
}
else if (last > maxSize-1){//改一改可以扩大
cout << "Input error, the size must be less than maxSize!\n";
cout << "Input the size again:";
}
else break;
}
cout << "\nInput the data for each element to create the list:" << endl;
for (int i = 0; i <= last; i++){
cout << "#" << i+1 << ":";
assert(cin >> data[i]);
}
}
template<typename T>void SeqList<T>::output(){
cout << "\nThe size of the list is:" << last+1 << endl;
for (int i = 0; i <= last; i++) cout << "#" << i+1 << ":\t" << data[i] << endl;
}
template<typename T>SeqList<T> SeqList<T>::operator = (SeqList<T> &L){//改
maxSize = L.Size();
last = L.Length()-1;
delete []data;//先清空
data = new T[maxSize];
if (data == NULL){
cerr << "Memory allocating error!" << endl;
exit(1);
}
for (int i = 1; i <= last+1; i++) data[i-1] = L.getData(i);
}
#endif
#include<iostream>
#include<stdlib.h>
#include"SeqList.h"
using namespace std;
int main()
{
SeqList<int> list(5);
int i,elem;
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>i>>elem;
list.Insert(i,elem);
}
cout<<list;
system("pause");
}
本代码参考书籍《数据结构(用面向对象方法与c++语言描述)》》;
400

被折叠的 条评论
为什么被折叠?



