面向对象链表和线性表操作

这则很多是教科数里面的知识,就当事一个课后总结

第一个是一个线性表的头文件和实现功能

#ifndef SEQLIST_H_
#define SEQLIST_H_
#include <iostream>
using namespace std;
const int defaultSize = 100;
template <class T>
class SeqList {
private:
    T *data; // 存放数组
    int maxSize; // 最大可容纳表项的项数
    int last; // 当前已存表项数
public:
    SeqList(int sz = defaultSize); // 构造函数
    ~SeqList( ) { delete[ ] data;} // 析构函数,用来释放内存
    int Length( ) const {return last + 1;} // 计算表长度
    void makeEmpty( ) { last = -1; } // 把表置空,在线性表中逻辑顺序和物理顺序一致,所以第i格表在第i个物理位置
    int Search(T x) const; // 在表中搜索x 的位置,返回位置序号(常数)
    bool Insert(int i, T x); // 插入
    bool Delete(int i);
    T* getData(const int i)const;
    void output( )const;
};
#include "SeqList.cpp"
#endif

#ifndef SEQLIST_CPP_
#define SEQLIST_CPP_
#include <iostream>
using namespace std;
#include "SeqList.h"
template <class T>        //模板类
SeqList<T>::SeqList(int sz) { // 构造函数
    if (sz > 0) {
        maxSize = sz;
        last = -1;
        data = new T[maxSize]; // 创建表存储数组
        if (data == NULL) { // 动态分配失败
            cerr <<"存储分配错误!"<< endl;//cerr是错误输出,cout其实差不多
            exit(1);
        }
    }
}




template<class T>
int SeqList<T>::Search(T x) const{
    if(last == -1)  return 0;    //0是初始化的数值
    else{
        for(int i = 0;i<=last;i++){
            if(i==data[i])      return i+1;//物理结构和逻辑结构相同
        }
        return 0;
    }
}/* 搜索*/
template<class T>  //插入操作,将前面各各向后面移动
bool  SeqList<T>::Insert(int i, T x){
    if(i>last||i<0)     return false;//超过表数或者小于表数
    if(last == -1)  return false;

    else{
        for(int j=last;j>=i;j--){
            data[j+1] = data[j];
        }
        data[i] = x;
        last++;
    }
    return true;
}
template<class T>             //和链表有区别,插入和删除差不多,
bool SeqList<T>::Delete(int i){
    if(last==-1)    return false;
    if(i<1||i>last) return false;
    else{
        for(int j =i;i<=last;i++){
            data[j-1] = data[j]; //从qian
        }
        last--;            //更新表数
    }
    return true;
}



template <class T>
void SeqList<T>::output( )const {
    cout <<"元素个数为"<< last + 1 <<" :"<< endl;
    for(int i = 0; i <= last; i++)
        cout << '#' << i+1 <<":"<< data[i] <<"; ";
    cout << endl;
}
template <class T>
inline T* SeqList<T>::getData(const int i)const {
    return (i > 0 && i <= last + 1) ? &data[i - 1] : NULL;
}
#endif

接下来是链表操作

#ifndef LIST_H_
#define LIST_H_
#include <iostream>
#include <cstdlib>
using namespace std;
template <class T>
struct LinkNode { // 链表结点类的定义
    T data; // 数据域
    LinkNode<T> *link; // 链指针域
    LinkNode( ) { link = NULL; } // 构造函数
    LinkNode(T item, LinkNode<T> *ptr = NULL) { // 构造函数
        data = item;
        link = ptr;
    }
    bool operator== (T x) { return data == x; } // 重载函数,判相等
    bool operator!= (T x) { return data != x; }
};
template <class T>
class List { // 单链表类定义, 不用继承也可实现
private:
    LinkNode<T> *first; // 表头指针
public:
    List( ); // 构造函数
    List(const T x);
    List(List<T>& L); // 复制构造函数
    ~List( ) { makeEmpty( ); delete first; } // 析构函数
    void makeEmpty( ); // 将链表置为空表
    int Length( ) const; // 计算链表的长度
    LinkNode<T> *Locate(const int i)const; // 定位第i 个元素
    T *getData(const int i)const; // 取出第i 元素值
    bool setData(const int i, const T x); // 更新第i 元素值
    bool IsEmpty( ) const { return first->link == NULL;} // 判表空否
/*--------------------Declare your  function here--------------*/
    bool Insert (const int i, const T x); // 在第i 元素后插入
    bool Remove(const int i, T& x); // 删除第i 个元素
    LinkNode<T> *Search(const T x)const; // 搜索含x 元素,设置一个指针指向表
    bool merge(List<T>* target);//结合两个链表
/*-----------------------------------------------------------------------------*/
    LinkNode<T> *getHead( ) const { return first; }
    void setHead(LinkNode<T> *f ) { first = f; }
// void Sort( ); // 排序
    void output( );
    List<T>& operator=(List<T>& L) {
        LinkNode<T> *srcptr = L.first;
        LinkNode<T> *destptr = first = new LinkNode<T>(srcptr->data);
//new LinkNode<T>(srcptr->data):这部分代码动态分配了一个新的节点,类型为 LinkNode<T>,并且将 srcptr 节点的数据(srcptr->data)作为构造函数的参数传递给了这个新节点。这就创建了一个包含 srcptr 节点数据的新节点。

first = new LinkNode<T>(srcptr->data):这一部分代码完成两个任务。首先,它分配了一个新的节点,并将新节点的地址赋值给 first 指针,这意味着 first 指向了这个新节点。其次,它也将这个新节点的地址赋值给 destptr 指针,所以 destptr 也指向了这个新节点。这样,first 和 destptr 指向了相同的节点,也就是新链表的头节点。

这个操作的效果是,在链表复制操作的开始,创建了一个新的链表,并且将 first 指向新链表的头节点,同时也将 destptr 指向新链表的头节点,以便在后续的循环中添加更多的节点到新链表中。

总之,这行代码是链表复制操作的起点,创建了新链表的头节点,并将 first 和 destptr 指向这个头节点,以便进行后续的节点复制。


        if(first == NULL) {                //进行错误处理
            cerr <<"存储分配失败!"<< endl;
            exit(1);
        }
        while(srcptr->link != NULL) {
            destptr->link = new LinkNode<T>(srcptr->link->data);//destptr->link = new LinkNode<T>(srcptr->link->data);:在每次迭代中,这一行代码会创建一个新的节点,新节点的数据值等于 srcptr 指向的节点的下一个节点的数据值,并将新节点链接到当前链表对象的尾部。
            if(destptr->link == NULL) {
                cerr <<"存储分配失败!"<< endl;
                exit(1);
            }
            destptr = destptr->link;//向下一个节点移动
            srcptr = srcptr->link;//向下一个移动
        }
        destptr->link = NULL;
        return *this;        //返回调用
    }
};
#include "List.cpp"
#endif

   #ifndef LIST_CPP_
#define LIST_CPP_
#include <iostream>
#include <cstdlib>
using namespace std;
#include "List.h"
template<class T>
List<T>::List( ) {
    first = new LinkNode<T>;
    if(first == NULL) {
        cerr <<" Memory allocation failed"<< endl;
        exit(1);
    }
}
template <class T>
List<T>::List(const T x) {
    first = new LinkNode<T>(x);
    if(first == NULL) {
        cerr <<" Memory allocation failed"<< endl;
        exit(1);
    }
}
template <class T>//链表初始化
List<T>::List(List<T>& L) {
    LinkNode<T> *srcptr = L.first;
    LinkNode<T> *destptr = first = new LinkNode<T>(srcptr->data);
    if(first == NULL) {
        cerr <<" Memory allocation failed"<< endl;
        exit(1);
    }
    while(srcptr->link != NULL) {
        destptr->link = new LinkNode<T>(srcptr->link->data);
        if(destptr->link == NULL) {
            cerr <<" Memory allocation failed"<< endl;
            exit(1);
        }
        destptr = destptr->link;
        srcptr = srcptr->link;
    }
    destptr->link = NULL;
}
template <class T>
void List<T>::makeEmpty( ) {
    LinkNode<T> *q;
    while (first->link != NULL) {//遍历链表
        q = first->link; // 保存被删结点
        first->link = q->link; // 从链上摘下该结点
        delete q; // 删除
    }
}
template <class T>
int List<T>::Length( ) const {
    LinkNode<T> *p = first->link;
    int count = 0;
    while ( p != NULL ) {// 逐个结点检测
        p = p->link;
        count++;
    }
    return count;
}
template <class T>
LinkNode<T>* List<T>::Locate (const int i)const {
// 函数返回表中第i 个元素的地址。若i < 0 或i 超出表中结点个数,则返回NULL。
    if (i < 0) return NULL; // i 不合理
    LinkNode<T> *current = first;
    int k = 0;
    while ( current != NULL && k < i ) {
        current = current->link;
        k++;
    }
    return current; // 返回第i 号结点地址或NULL
}

/*----------Complete your funcrtions here--------------------------*/
template<class T>//插入
bool List<T>::Insert(const int i, const T x) {
    LinkNode<T> *current = Locate(i);
    LinkNode<T> *newNode = new LinkNode<T>(x,current->link);
    if(current == NULL){
        cerr<<"无效插入位置"<<endl;
        return false;
    }
    if(newNode == NULL) {
        cerr<<"内存分配错误"<<endl;
        return false;
        exit(1);
    }
   newNode->link = current->link;
    current->link = newNode;
    return true;
}
template<class T>
LinkNode<T>* List<T>::Search(const T x) const {
    LinkNode<T> *current = first->link;
    while (current != NULL && current->data != x)
        current = current->link;
    return current;
}

template <class T>//删除
bool List<T>::Remove(const int i,T& x){
    LinkNode<T> *del,*current;
    if(i<=1) {del =first,first = first->link;}
    else{
        current = first;
        for(int k=1;k<i-1;k++){
            if(current == NULL) return false;
            else current = current -> link;
        }
        if(current == NULL || current->link==NULL){
            return false;
        }
        del = current->link;
        current->link = del->link;
    }
        x = del->data;
        delete del;
        return true;
}
template<class T>
bool List<T>::merge(List<T>* target)
{
    LinkNode<T>* last = Locate(Length());
    last->link = target->getHead()->link;
    return true;
}
/*-----------------------------------------------------------------------------------*/


template <class T>
T* List<T>::getData(const int i) const {
// 取出表中第i 个元素的值
    if(i <= 0) return NULL;
    LinkNode<T> *current = Locate(i);
    if( current != NULL )
        return &(current->data);
    else
        return NULL;
}
template <class T>
bool List<T>::setData(const int i, const T x) {
// 更新第i 元素值
    if(i <= 0) return false;
    LinkNode<T> *current = Locate(i);
    if(current != NULL) {
        current -> data = x;
        return true;
    }
    else return false;
}
template <class T>
void List<T>::output( ) {
    LinkNode<T> *p = first->link;
    int i = 0;
    cout <<"Elements in linked list: "<< endl;
    while(p) {
        cout << '#' << i++ <<":"<< p->data <<"";
        p = p->link;
    }
    cout << endl;
}
#endif

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值