在主函数中调用了两次调用但是下面输出窗口只有一次
代码输出结果如下,请大家帮我看看哪里出了问题
template
struct Node
{
T3 data;
Node> *next;
};
linklist.h
#include "Node.h"
template<class T>
class LinkList
{
public:
LinkList();//无参构造函数
LinkList(T a[],int n);//有参构造函数(头插法)
LinkList(int n,T a[]);//有参构造函数(尾插法)
~LinkList();//析构函数
int Length();//获取链表长度
T Get(int i);//按位查找
int Locate(T x);//按值查找
void Insert(int i,T x);//插入
T Delete(int i);//删除
void Set(int i,T x);//设置数据域的值
void PrintList();//遍历链表
private:
Node*first;//头指针
};
linklist.cpp
#include "linkList.h"
#include
using namespace std;
//按位查找
template
T LinkList::Get(int i)
{
Node*p = first;//创建工作指针,指向头结点
int j = 0;//计数
while(p&&j//p指针指向的位置不为空并且没有到第i个结点
{
p = p->next;//工作指针p指向下一个位置
j++;//到下一个结点
}
if(!p)throw "位置不对";//p指向的位置为空
else return p->data;//找到了
}
//插入,由于单链表带头结点,表头、表中、表位三种情况的操作语句一致
template
void LinkList::Insert(int i,T x)
{
Node *p = first;//创建工作指针
Node *s;//创建指向新结点的指针
int j = 0;//计数
while(p&&j1)//p指向的位置不为空并且没要到第i-1个结点
{
p = p->next;//p指向下一个结点
j++;//迭代器增加
}
if(!p) throw"位置错误";//p指向的位置为空抛出异常
else
{
s = new Node;//创建一个结点,让s指针指向它
s->data = x;//将需要插入的值存入新快结点的数据域
s->next = p->next;//将原来第i个节点的地址存入新结点的指针域
p->next = s;//将新结点的地址存入第i-1个结点的指针域
}
}
//删除,最后一个结点没有后继结点(需要两个工作指针)
template
T LinkList::Delete(int i)
{
Node *p = first;//创建工作指针
Node *q;//创建工作指针2
int j = 0;//计数
T x;//存储需要删除的结点数据域的值
while(p&&j1)//p指向的位置不为空并且没要到第i-1个结点
{
p = p->next;//p指向下一个结点
j++;//迭代器增加
}
if(!p||!p->next) throw"位置异常";
else
{
q = p->next;//q指向需要删除的结点
x = q->data;//将需要删除的结点的数据域的内容存入x
p->next = q->next;//将第i-1个结点和原来第i+1个结点连接起来
delete q;//释放第i个结点的空间
return x;//返回删除结点数据域中的内容
}
}
//无参数构造函数
template
LinkList::LinkList()
{
first = new Node;
first->next = NULL;//将头结点的指针域设置为空
}
//有参数构造函数(头插法)
template
LinkList::LinkList(T a[],int n)
{
Node *s;//指向待插入结点的指针
first = new Node;//创建一个头结点
first->next = NULL;
for(int i = 0;i;//s指向待插入结点
s->data = a[i];
s->next = first->next;//将新结点与第一个结点连接
first->next = s;//将插入的结点与头结点相连接
}
}
//有参数的构造函数(尾插法)
template
LinkList::LinkList(int n,T a[])
{
first = new Node;//创建头结点
Node *rear=first,*s;//创建工作指针和指向待插入结点的指针
for(int i = 0;i;//创建待插入的结点
s->data = a[i];//给数据域赋值
rear->next = s;//连接最后一个结点和新插入的结点
rear = s;//rear指向最后一个结点
}
rear->next = NULL;
}
//析构函数
template
LinkList::~LinkList()
{
Node *p = first;//用于移位的工作指针
Node *q;//用于释放空间的工作指针
while(p)//p指向的位置不为空
{
q = p;//q指向p指向的结点
p = p->next;//p移动到下一个结点
delete q;
}
}
//计算链表的长度
template
int LinkList::Length()
{
Node *p = first;//用于移位的工作指针
int j = 0;
while(p->next)
{
p = p->next;//p移动到下一个结点
j++;
}
return j;
}
//按值查找
template
int LinkList::Locate(T x)
{
Node *p = first;//用于移位的工作指针
int j = 0;//计数
while(p)
{
p = p->next;//p移动到下一个结点
j++;
if(x==p->data)
return j;
}
}
//遍历链表
template
void LinkList::PrintList()
{
Node *p = first;//用于移位的工作指针
while(p) {
p = p->next;//p移动到下一个结点
cout << p->data << endl;//输出p当前指向的结点的数据域的值
}
}
//设置数据域的值
template
void LinkList::Set(int i,T x)
{
Node *p = first;
int j = 0;
while(p&&jnext;//P指向下一个结点
j++;
}
if(!p)throw"位置错误";
else
{
p->data = x;
}
}
main.cpp
#include
#include "linkList.cpp"
using namespace std;
int main() {
int a[5] = {1,2,3,4,5};
LinkList<int> L1(5,a);//头插法创建单链表
LinkList<int> L2(a,5);//尾插法创建单链表
try
{
cout<<"单链表L1的长度为:"<Length()<"遍历L1链表"<PrintList();
cout<<"单链表L2的长度为:"<Length()<"遍历L2链表"<PrintList();
}
catch(const char *msg){cout<return 0;
}
通过 static 关键字
静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。
void fun()
{
static bool first = false;//赋初值
if(first)
{
return true;//只执行一次
}
first = true;
//接下来实现自己想要实现的过程内容
}
```c++
遍历打印链表PrintList()出错了,段错误,p = p->next 之后再访问 p->data,如果已经到了最后一个节点了,p已经为NULL了,再访问data就出错了,可以改成下面这样
//遍历链表
template<class T>
void LinkList<T>::PrintList()
{
Node<T> *p = first;//用于移位的工作指针
while(p) {
p = p->next;//p移动到下一个结点
if(p) {
cout << p->data << endl;//输出p当前指向的结点的数据域的值
}
}
}