数据结构之线性结构的顺序表和递归的简单说明

用递归来实现:输入一个数字N,把1到N打印输出。

#include<stdio.h>
void Print(int n);
int main()
{
    int n;
    scanf("%d",&n);
    Print(n);

}
Print(int n)
{
    if(n)
    {
        Print(n-1);
        printf("%d\n",n);
    }
}
运行结果

用递归感觉似乎在炫技,计算机可能并不想计算递归的程序。对递归思想掌握比较好的人,可能会经常写出递归的代码。递归函数很吃空间,可能会使程序崩溃掉。

运行结果

当输入的n = 100000时候,程序直接崩溃掉了。但是如果用循环来实现的话,程序是能够正常运行的。

数据对象有逻辑上的结构和物理存储结构。

Abstract Data Type(抽象数据类型):它包括数据对象集和数据集合相关的操作集。其抽象体现在:描述数据类型的方法不依赖于具体的实现,也不关心数据具体的类型。可以和C++中的模板的概念进行对照。


线性结构是简单且常用的数据结构,而线性表是一种典型的线性结构。一般情况下,在程序中存储数据,最简单有效的方法是把它存放在线性表中。线性表是一个有限的序列,它的第一个表项称为表头,最后一个表项称为表尾。除了表头和表尾,其它表项只有一个前驱和后继。

线性表中顺序表的类定义:

#include<iostream>
#include<stdlib.h>
const int defaultSize = 100;
template<typename T>
class SeqList
{
private:
    T * data;
    int maxSize;
    int last;//当前已存表项的最后位置,用数组存储从0开始计算
    void reSize(int newSize);
public:
    SeqList(int sz = defaultSize);
    SeqList(SeqList<T> &L);
    ~SeqList(){delete[] data;}
    int Size()const{return maxSize;}//直接用内联的方式定义函数
    int Length()const{return last + 1;}
    int Search(T& x)const;
    int Locata(int i)const;
    T * getData(int i)const
    {
        return (i > 0 && i <= last + 1)? &data[i-1]: NULL;
    }
    void setData(int i ,T&x)
    {
        if(i > 0 && i <= last + 1) data[i-1] = x;
    }
    bool Insert(int i,T& x);
    bool Romve(int i, T& x);
    bool IsEmpty(){return(last == -1)?true:false;}
    bool IsFull(){return(maxSize-1 == last)? true:false;}
    void input();
    void output();
    SeqList<T>operator=(SeqList<T>& L);
};

下面对顺序表的各种方法实现并验证:

#include<iostream>
#include<stdlib.h>
using namespace std;
const int defaultSize = 100;
template<typename T>
class SeqList
{
private:
    T * data;
    int maxSize;
    int last;//当前已存表项的最后位置
    void reSize(int newSize);
public:
    SeqList(int sz = defaultSize);
    SeqList(SeqList<T> &L);
    ~SeqList(){delete[] data;}
    int Size()const{return maxSize;}
    int Length()const{return last + 1;}
    int Search(T& x)const;
    int Locate (int i)const;
    T * getData(int i)const
    {
        return (i > 0 && i <= last + 1)? &data[i-1]: NULL;
    }
    void setData(int i ,T&x)
    {
        if(i > 0 && i <= last + 1) data[i-1] = x;
    }
    bool Insert(int i,T& x);
    bool Romve(int i, T& x);
    bool IsEmpty(){return(last == -1)?true:false;}
    bool IsFull(){return(maxSize-1 == last)? true:false;}
    void input();
    void output();
    SeqList<T>& operator=(SeqList<T>& L);
};
template<typename T>
SeqList<T>::SeqList(int sz)
{
    maxSize = sz;last = -1;
    data = new T[maxSize];
    if(data == NULL)
    {
        cerr<<"存储分配错误!"<<endl;
        exit(1);
    }
}
template<typename T>
SeqList<T>::SeqList(SeqList<T>& L)
{
    maxSize = L.maxSize;last = L.Length() - 1;
    data = new T[maxSize];
    if(data == NULL)
    {
        cerr<<"存储分配错误!"<<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<<"无效数组的大小"<<endl;
        return;
    }
    if(newSize != maxSize)
    {
        T* newarrar = new T[newSize];
        if(newarrar == NULL)
        {
             cerr<<"存储分配错误!"<<endl;
             exit(1);
        }
        int n = last + 1;
        T *srcptr = data;
        T *destptr = newarrar;
        while(n--)
        {
            *destptr++ = *srcptr++;
        }
        delete []data;
        data = newarrar;
        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;
        }
}
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(IsFull()) 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>::Romve(int i, T& x)
{
    if(IsFull()) 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>::input()
{
    cout<<"开始建立顺序表,请输入表中元素的个数:";
    while(1)
    {
        cin>>last;
        if(last <= maxSize-1)break;
        cout<<"表元素输入的个数有误,范围不能超过:"<<maxSize-1<<":";
    }
    for(int i=0;i<=last;i++)
    {
        cin>>data[i];cout<<i+1<<endl;
    }
}
template<typename T>
void SeqList<T>::output()
{
    cout<<"顺序表当前元素的最后位置为:"<<last<<endl;
    for(int i=0;i<=last;i++)
        cout<<"#"<<i+1<<":"<<data[i]<<endl;
}

template<typename T>
SeqList<T>& SeqList<T>::operator=(SeqList<T> &L)
{
    if(this != &L)
    {
        maxSize = L.maxSize;
        last = L.Length() - 1;
        data = new T[maxSize];
        if(data == NULL)
        {
            cerr<<"存储分配错误!"<<endl;
            exit(1);
        }
        for(int i=1; i<=last+1; i++)
        {
           data[i-1] = *(L.getData(i));
        }
    }
   return *this;
}

int main()
{
    //int a = 55;
    //int b;
    SeqList<int>s1;
    SeqList<int>s2;
    s1.input();
    s2 = s1;
    s2.output();
    //cout<<"romve ->"<<b<<endl;
}

PS:在重载赋值运算符的时候,赋值的等式两边类型不同,需要用()强制转换一下,统一类型。

这个程序还有个问题:因为用的是数组的结构,所以是从下标0开始存的,last是存的最后一个元素。本程序在输入时,征求输入个数的时候用的是last,但其实大家心里要明白输入的个数是last+1个(因为数组是从0开始存的)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值