顺序表的实现

使用c++实现一下常用的数据结构,参考书为《数据结构、算法与应用-c++语言描述》。

此次代码为顺序表,为了保证通用性采用模板机制,算法本身没有什么难度,毕竟是基础算法,但是长时间不用c++,一些高级特性和陷阱着实让人难受。

此次代码共分三个文件:

1、Sq_list.h :实现顺序表的结构和基本操作。

2、excp.h :实现异常类,关于命名空间的问题,直接将异常类加入到std空间内。

3、sq.cpp :主函数,简单测试,可稍加简单修改,转为交互式程序。

Sq_list.h
//construct the sq_list with template 
#ifndef _sqList_ 
#define _sqList_
#include <iostream>
#include "excp.h"
using namespace std;

template<class T>
class sqList {
public:
    sqList(int maxSizel = 10);
    ~sqList(){delete [] data;}
    bool isEmpty() const{return length == 0;}
    template<class Type>
    friend ostream& operator<<(ostream& out, const sqList<Type>& x);
    int getLength() const{return length;}
    bool findElement(int k, T& x) const;//get the kth value in the var x
    int searchElement(T& x) const;//return the index of the var x
    sqList<T>& deleteElement(int k, T& x);//remove the kth element and return it by x
    sqList<T>& insertElement(int k, const T& x);//Insert x
    T* getData() const {return data;}
private:
    T *data;
    int length;
    int maxSize;
};

template<class T>
sqList<T>::sqList(int maxSizel)
{
    maxSize = maxSizel;
    data = new T[maxSize];
    length = 0;
}

template<class T>
bool sqList<T>::findElement(int k, T& x) const
{
    if (k<1 || k>length)
        return false;
    x = data[k-1];
    return true;
}

template<class T>
int sqList<T>::searchElement(T& x) const
{
    for (int i=0; i<length; i++)
        if (data[i] == x)
            return i+1;
    return 0;
}

template<class T>
sqList<T>& sqList<T>::deleteElement(int k, T& x)
{
    if (findElement(k, x))
    {
        for (int i=k; i<length; i++)
            data[i-1] = data[i];
        length--;
        return *this;
    }
    else
        throw OutOfBounds();
}

template<class T>
sqList<T>& sqList<T>::insertElement(int k, const T& x)
{
    if (k<1 || k>length+1)
        throw OutOfBounds();
    if (length >= maxSize)
        throw FullMemery();
    for (int i=length-1; i>=k-1; i--)
        data[i+1] = data[i];
    data[k-1] = x;
    length++;
    return *this;
}

template<class Type>
ostream& operator<<(ostream& out, const sqList<Type>& x)
{
    Type* t = x.getData();
    for (int i=0; i<x.getLength(); i++)
        out<<t[i]<<" ";
    out<<endl;
    return out;
}
#endif
excp.h
#ifndef _EXCP_
#define _EXCP_
#include <new>
using namespace std;

class OutOfBounds {
public:
    OutOfBounds(){}
};

class FullMemery {
public:
    FullMemery(){}
};

void my_new_handler()
{
    throw FullMemery();
}

new_handler old_handler = set_new_handler(my_new_handler);
#endif

excp.h
#ifndef _EXCP_
#define _EXCP_
#include <new>
using namespace std;

class OutOfBounds {
public:
    OutOfBounds(){}
};

class FullMemery {
public:
    FullMemery(){}
};

void my_new_handler()
{
    throw FullMemery();
}

new_handler old_handler = set_new_handler(my_new_handler);
#endif

问题总结:

1、在模板类中重载操作符,稳妥的一种方法就是像程序中这样在外层模板中(类模板)对于友元重载函数声名成另一模板,否则会提示basic_ostream找不到匹配函数什么的,估计是编译器在定义ostream的时候把所有可用的查了一遍,结果没找到合适的。

2、对于异常,使用自定义的异常,方便定制。

3、良好的编程习惯,遵循最小权限原则,对于公有函数要进行一定的限制。

4、写代码要小心,错将#ifndef写成#ifdef浪费了大量时间。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值