第一次自己手搓链表成功
主要难点有
1.循环的临界标志的选取,是p->next==NULL还是p==NULL(容易运行卡壳)
2.特别是在remove函数中对不合法操作的防御(后面发现还是在上一层的函数中直接掐断(跳过运行)会比较省心)
3.还有就是老问题,自己写的delete(析构函数)会出现异常,oj显示运行时异常,clion略微卡壳
题目描述
结点数据类型为int的单链表类CIntList可定义如下:
class CNode
{
public:
int data;
CNode *next;
};
class CIntList
{
private:
CNode *head;
public:
CIntList();
void append(int a); //加到链表最后
void insert(int a, int n); //在第n个结点后加
void remove(int n); //移除第n个结点
int get(int n); //返回第n个结点的数据
void set(int a, int n); //将第n个节点的数据改成a
void print();
~CIntList();
};
试将其改成结点数据类型用参数表示的类模板CList。
输入
第一行输入测试次数
每次测试输入5行,格式为:
数据类型(I:int, D:double, S:string) 数据个数n 数据1 数据2 ... 数据n
插入节点号(0表示插在第1个结点前面) 数据
返回结点号
删除结点号
修改结点号 数据
输出
每次测试输出二行.第1行输出返回操作获得的数据(如出错则输出error),第2行输出所有操作后链表全部结点的数据.
输入样例 | 输出样例 |
3 | error\n 2 40 3 5 7 -10\n 60.4\n 2.3 10.05 -3.7 60.4 -1.8 5.9\n good\n good this is work test.\n |
#include<iostream>
#include<string>
#include<cstring>
using namespace std;
template<class T>
class CNode
{
public:
T data;
CNode *next;
};
template<class T>
class CList
{
private:
CNode<T>*head;
public:
CList(){
head = NULL;
}
void append(T a) //加到链表最后
{
if(head == NULL)
{
head = new CNode<T>;
head->data = a;
head->next = NULL;
}
else
{
CNode<T>*node;
node = head;
while(node->next!=NULL)
{
node = node->next;
}
CNode<T>*p = new CNode<T> ;
p->data = a;
p->next = NULL ;
node->next = p;
}
}
void insert(T a, int n) //在第n个结点后加
{
if( n == 0 ){
CNode<T>*p = new CNode<T> ;
p->data = a;
p->next = head ;
head = p;
}
else{
CNode<T>*node;
node = head;
for( int i = 1 ; i < n ; i++ )
{
node = node->next;
}
CNode<T>*p = new CNode<T> ;
p->data = a;
p->next = node->next ;
node->next = p;
}
}
void remove(int n)//移除第n个结点
{
if( n == 1 ){
head = head->next;
}
else{
CNode<T>*node;
node = head;
for( int i = 2 ; i < n ; i++ )
{
if(node->next!=NULL)
node = node->next;
}
if( node->next!=NULL)
{
CNode<T>*p;
p = node->next->next;
delete[](node->next);
node->next = p;
}
}
}
T get(int n) //返回第n个结点的数据
{
CNode<T>*p;
p = head;
for( int i = 1 ; i < n ; i++ )
{
p = p->next;
}
if( p == NULL)
return 0;
else
return p->data;
}
void set(T a, int n) //将第n个节点的数据改成a
{
CNode<T>*p;
p = head;
for( int i = 1 ; i < n ; i++ )
{
p = p->next;
}
p->data = a;
}
void print()
{
CNode<T>*p;
for( p = head ; p != NULL ; p = p->next )
{
cout<<p->data;
if(p->next == NULL)
cout<<endl;
else
cout<<" ";
}
// cout<<"///";
}
~CList()
{
// CNode<T>*p;
// while(head == NULL )
// {
// p = head ;
// head = head->next;
// delete[]p;
// }
// delete[]head;
}
};
template<class T>
void work(CList<T>&P){
int n,length;
T test;
cin>>n;
length=n;
for( int i = 0 ; i < n ; i++ )
{
cin>>test;
P.append(test);
}
cin>>n>>test;//插入
P.insert(test,n);
cin>>n;//show
if(n>length)
cout<<"error"<<endl;
else
cout<<P.get(n)<<endl;
cin>>n;//delete
P.remove(n);
cin>>n>>test;
P.set(test,n);
P.print();
}
int main(){
int t;
cin>>t;
char Type;
while(t--)
{
cin>>Type;
if(Type=='I')
{
int test;
CList<int> P;
work(P);
}
else if(Type == 'D')
{
double test;
CList<double>P;
work(P);
}
else if(Type == 'S')
{
string test;
CList<string>P;
work(P);
}
}
return 0;
}