这个周末,复习了线性表的常用存储方式。以前总是看得多,写的少,这次真的写起来,发现自己手生的很,都是眼高手低的结果。在写程序的过程中,也遇到了一些问题和以前没有注意的地方。这次深深的体会到了:自己手写一遍比看书5遍都收获大。所以,借此奉劝和我一样眼高手低的园友:实践,实践,再实践……
下面介绍常用的四种存储方式,附上源码:
顺序表:这是大家最为熟悉的一种描述,相对比较简单。
优点:存储空间小,不需要额外增加空间,元素按位置查找方便,速度快。
缺点:
必须预先分配空间,在删除和插入操作时,需要移动元素,因此时间复杂度与元素大小成线性关系,面对大型类对象时,此缺点是致命的。
源码:

Code

/**//********************************************************************
created: 2008/05/24
created: 24:5:2008 21:18
filename: MyArrayList.h
file path:
file base: MyArrayList
file ext: h
author: CY
purpose: 线性表的顺序存储
*********************************************************************/

#ifndef _MYARRAYLIST_H_
#define _MYARRAYLIST_H_

#include <iostream.h>
#include <cstdlib>
#include <exception>

template<class T>
class MyArrayList


{
public:
MyArrayList(int MaxSpace = 100) //容量初始化为MaxSpace

{
m_size = MaxSpace;
element = new T[m_size];
m_length = 0;
}
~MyArrayList()

{
delete []element;
}

bool IsEmpty() const //判断链表空

{
return m_length == 0;
}

int Length() const //求当前元素个数

{
return m_length;
}

bool FindK(int k, T& x) const; //将第k个元素返回给x

int Search(const T& x) const; //返回元素x所在位置

MyArrayList<T>& DeleteK(int k, T& x); //删除第k个元素

MyArrayList<T>& InsertK(int k, const T& x); //在第k个元素后插入元素x

friend ostream& operator <<(ostream& out,const MyArrayList<T>& mylist);
private:
int m_size; //定义数组容量
int m_length; //当前元素个数
T *element; //动态数组
};


template<class T>
bool MyArrayList<T>::FindK(int k, T& x) const


{
if (k < 1 || k > m_length)

{
return false;
}
x = element[k-1];
return true;
}

template<class T>
int MyArrayList<T>::Search(const T& x) const


{
int i;
for (i=1; i < m_length+1; i++)

{
if ( x == element[i-1])

{
break;
}
}
return (i==m_length+1? -1:i);
}

template<class T>
MyArrayList<T>& MyArrayList<T>::DeleteK(int k, T& x)


{
if (FindK(k,x)) //删除位置合法

{
for (int i=k; i < m_length; i++)

{
element[i-1] = element[i];//删除位置后面的元素前移一位
}
m_length--; //长度减一
return *this;
}
else throw exception(); //删除位置不合法
}

template<class T>
MyArrayList<T>& MyArrayList<T>::InsertK(int k,const T& x)


{
if ( m_length == m_size || k<1 || k>m_length+1) //插入位置不合法

{
throw exception();
}
m_length++;
for (int i=m_length; i>=k; i--)

{
element[i] = element[i-1];
}
element[k-1] = x;
return *this;
}

template<class T>
ostream& operator <<(ostream& out,const MyArrayList<T>& mylist)


{
for (int i=0; i<mylist.m_length; i++)

{
out << mylist.element[i]<<" ";
}
out << endl;
return out;
}
#endif

链表:
优点:删除和插入操作不需要移动元素,表长可动态改变。
缺点:按位置查找需要遍历链表,存储需要额外的空间。
源码:

Code

/**//********************************************************************
created: 2008/05/23
created: 24:5:2008 9:48
filename: MyNodeList.h
file path:
file base: MyNodeList
file ext: h
author: CY
purpose: 线性表的链式存储结构
*********************************************************************/
#ifndef _MYNODELIST_H_
#define _MYNODELIST_H_
#include <iostream.h>
#include <cstdlib>
#include <exception>

template<class T>
struct Node //定义结点


{
T m_data;
Node<T>* m_link;
};


template<class T>
class MyNodeList


{
friend ostream& operator<<(ostream& out, const MyNodeList<T>& mylist);//重载运算符
public:
MyNodeList()

{
Head = 0; //置头结点为空
}

~MyNodeList();

bool IsEmpty() const //判断链表空

{
return Head==0;
}

int Length() const; //求链表长度

bool FindK(int k, T &x);//将第k个节点内容返回到x

int Search(const T &x); //搜索x所在位置

MyNodeList<T>& DeleteK(int k, T &x); //删除第k个节点,并将其数据返回给x

MyNodeList<T>& InsertK(int k, const T &x);//在第k个节点后插入x

private:
Node<T>* Head;
};


template<class T>
int MyNodeList<T>::Length() const


{
Node<T> *p=Head;
int i=0;
while (p != 0)

{
i++;
p = p->m_link;
}
return i;
}

template<class T>
bool MyNodeList<T>::FindK(int k, T &x)


{
Node<T> *p=Head;
int i=0;

if ( k<1)//位置不正确

{
throw exception();
}
while( p && i != k)

{
i++;
p=p->m_link;
}
if ( i == k)//找到第k个节点

{
x = p->m_data;
return true;
}
return false;
}

template<class T>
int MyNodeList<T>::Search(const T &x)


{
Node<T> *p=Head;
int i=0;
while(p && p->m_data!=x)

{
i++;
p=p->m_link;
}
if (p->m_data == x)

{
return i;
}
return -1;
}

template<class T>
MyNodeList<T>& MyNodeList<T>::DeleteK(int k, T &x)


{
Node<T>* p=Head;
int i=0;

if (k<1 || p==0)

{
throw exception();
}

if (k==1)
![]()