这则很多是教科数里面的知识,就当事一个课后总结
第一个是一个线性表的头文件和实现功能
#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