计算机小混子 2022-10-04 21:49 采纳率: 100%
浏览 39
已结题

C++链表调用两次遍历,结果却只输出一次

在主函数中调用了两次调用但是下面输出窗口只有一次
代码输出结果如下,请大家帮我看看哪里出了问题

img


截屏2022-10-04 21.33.05.png
Node.h

template <class T3>
struct Node
{
    T3 data;
    Node<T3> *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<T>*first;//头指针
};


linklist.cpp

#include "linkList.h"
#include <iostream>
using namespace std;
//按位查找
template<class T>
T LinkList<T>::Get(int i)
{
    Node<T>*p = first;//创建工作指针,指向头结点
    int j = 0;//计数
    while(p&&j<i)//p指针指向的位置不为空并且没有到第i个结点
    {
        p = p->next;//工作指针p指向下一个位置
        j++;//到下一个结点
    }
    if(!p)throw "位置不对";//p指向的位置为空
    else return p->data;//找到了
}

//插入,由于单链表带头结点,表头、表中、表位三种情况的操作语句一致
template<class T>
void LinkList<T>::Insert(int i,T x)
{
    Node<T> *p = first;//创建工作指针
    Node<T> *s;//创建指向新结点的指针
    int j = 0;//计数
    while(p&&j<i-1)//p指向的位置不为空并且没要到第i-1个结点
    {
        p = p->next;//p指向下一个结点
        j++;//迭代器增加
    }
    if(!p) throw"位置错误";//p指向的位置为空抛出异常
    else
    {
        s = new Node<T>;//创建一个结点,让s指针指向它
        s->data = x;//将需要插入的值存入新快结点的数据域
        s->next = p->next;//将原来第i个节点的地址存入新结点的指针域
        p->next = s;//将新结点的地址存入第i-1个结点的指针域
    }
}

//删除,最后一个结点没有后继结点(需要两个工作指针)
template<class T>
T LinkList<T>::Delete(int i)
{
    Node<T> *p = first;//创建工作指针
    Node<T> *q;//创建工作指针2
    int j = 0;//计数
    T x;//存储需要删除的结点数据域的值
    while(p&&j<i-1)//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<class T>
LinkList<T>::LinkList()
{
    first = new Node<T>;
    first->next = NULL;//将头结点的指针域设置为空
}

//有参数构造函数(头插法)
template<class T>
LinkList<T>::LinkList(T a[],int n)
{
    Node<T> *s;//指向待插入结点的指针
    first = new Node<T>;//创建一个头结点
    first->next = NULL;
    for(int i = 0;i<n;i++)
    {
        s = new Node<T>;//s指向待插入结点
        s->data = a[i];
        s->next = first->next;//将新结点与第一个结点连接
        first->next = s;//将插入的结点与头结点相连接
    }
}

//有参数的构造函数(尾插法)
template<class T>
LinkList<T>::LinkList(int n,T a[])
{
    first = new Node<T>;//创建头结点
    Node<T> *rear=first,*s;//创建工作指针和指向待插入结点的指针
    for(int i = 0;i<n;i++)
    {
        s = new Node<T>;//创建待插入的结点
        s->data = a[i];//给数据域赋值
        rear->next = s;//连接最后一个结点和新插入的结点
        rear = s;//rear指向最后一个结点
    }
    rear->next = NULL;
}

//析构函数
template<class T>
LinkList<T>::~LinkList()
{
    Node<T> *p = first;//用于移位的工作指针
    Node<T> *q;//用于释放空间的工作指针
    while(p)//p指向的位置不为空
    {
        q = p;//q指向p指向的结点
        p = p->next;//p移动到下一个结点
        delete q;
    }
}

//计算链表的长度
template<class T>
int LinkList<T>::Length()
{
    Node<T> *p = first;//用于移位的工作指针
    int j = 0;
    while(p->next)
    {
        p = p->next;//p移动到下一个结点
        j++;
    }
    return j;
}

//按值查找
template<class T>
int LinkList<T>::Locate(T x)
{
    Node<T> *p = first;//用于移位的工作指针
    int j = 0;//计数
    while(p)
    {
        p = p->next;//p移动到下一个结点
        j++;
        if(x==p->data)
            return j;
    }
}

//遍历链表
template<class T>
void LinkList<T>::PrintList()
{
    Node<T> *p = first;//用于移位的工作指针
    while(p) {
        p = p->next;//p移动到下一个结点
        cout << p->data << endl;//输出p当前指向的结点的数据域的值
    }
}

//设置数据域的值
template<class T>
void LinkList<T>::Set(int i,T x)
{
    Node<T> *p = first;
    int j = 0;
    while(p&&j<i)
    {
        p = p->next;//P指向下一个结点
        j++;
    }
    if(!p)throw"位置错误";
    else
    {
        p->data = x;
    }

}



main.cpp

#include <iostream>
#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的长度为:"<<L1.Length()<<endl;
        cout<<"遍历L1链表"<<endl;
        L1.PrintList();
        cout<<"单链表L2的长度为:"<<L2.Length()<<endl;
        cout<<"遍历L2链表"<<endl;
        L2.PrintList();
    }
    catch(const char *msg){cout<<msg<<endl;}

    return 0;
}


  • 写回答

2条回答 默认 最新

  • 藤森有只 2022-10-04 21:54
    关注

    通过 static 关键字
    静态局部变量使用static修饰符定义,即使在声明时未赋初值,编译器也会把它初始化为0。且静态局部变量存储于进程的全局数据区,即使函数返回,它的值也会保持不变。

    void fun()
    {
        static bool first = false;//赋初值
        if(first)
        {
            return true;//只执行一次
        }
        first = true;
    //接下来实现自己想要实现的过程内容
    }
    ```c++
    
    
    
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 11月26日
  • 已采纳回答 11月18日
  • 创建了问题 10月4日

悬赏问题

  • ¥15 Marscode IDE 如何预览新建的 HTML 文件
  • ¥15 K8S部署二进制集群过程中calico一直报错
  • ¥15 java python或者任何一种编程语言复刻一个网页
  • ¥20 如何通过代码传输视频到亚马逊平台
  • ¥15 php查询mysql数据库并显示至下拉列表中
  • ¥15 freertos下使用外部中断失效
  • ¥15 输入的char字符转为int类型,不是对应的ascall码,如何才能使之转换为对应ascall码?或者使输入的char字符可以正常与其他字符比较?
  • ¥15 devserver配置完 启动服务 无法访问static上的资源
  • ¥15 解决websocket跟c#客户端通信
  • ¥30 Python调用dll文件输出Nan重置dll状态