• 面试高频题:单链表的逆置操作/链表逆序


     函数内对形参的操作并不能影响实参,函数内修改的是实参的副本。要想在函数内部修改输入参数,要么传入的是实参的引用,要么传入的是实参的地址。


    #include <iostream>
    #include <cstdlib>
    #include <cstring>//strlen
    using namespace std;
    //template <class T>
    class node
    {
          public:
              node * next;
              char data;
    };
    node *node_reverse(node *head)
    {
        //如果一个函数的输入参数有指针,一定要记住判断指针时候为空
        //1>:在使用一个指针之前一定要判断它是否为空;
        //2>:使用完后要释放由指针指向的存储单元
        //3>:释放完存储单元后要将指针赋值为NULL;
         if(head->next==NULL || head==NULL)
              return head;
    
    
    
         node* pPre=head;    //先前指针
         node* pCurrent=pPre->next;  //当前指针
         node* pNext=NULL;       //后继指针
         //要注意这里面的顺序,先将pNext保存在pCurrent中,
         //然后再将pNext移动到下一个元素,然后才能改动pCurrent
         //
         while(pCurrent!=NULL)
         {
            pNext=pCurrent->next;
            pCurrent->next=pPre;
            pPre=pCurrent;
            pCurrent=pNext;
    
         }
         head->next=NULL;
         head=pPre;
         return head;
    }
    /**************
    void init_node(node *tail,char *init_array)
    这样声明函数是不正确的,函数的原意是通过数组初始化链表
    若链表结点传入的是指针,则并不能创建链表,除非是二维指针
    即指向指针的指针
    ****************/
    void init_node_by_referenceToPointer(node *&tail,const char *init_array)
    {
         node * tmp = NULL;
         int j=strlen(init_array);
         for(int i=0; i<j; i++)
         {
             tmp = new node;
             tmp->data = *(init_array+i);
             tmp->next = tail;
             tail = tmp;
         }
    }
    /***************************************
    void init_node_by_referenceToPointer(node &*tail,char *init_array)
    error: cannot declare pointer to 'class node&'
    ****************************************/
    void init_node_by_pointerToPointer(node **tail,const char *init_array)
    {
         node * tmp = NULL;
         int j=strlen(init_array);
         for(int i=0; i<j; i++)
         {
             tmp = new node;
             tmp->data = *(init_array+i);
             tmp->next = *tail;
             *tail = tmp;
         }
    }
    void display(node *nn,char *print=NULL)
    {
        if(nn==NULL)
        {
            cout << "no data to display
    ";
            return ;
        }
        cout<<print;
        node *dis = nn;
        while(dis!=NULL)
        {
            cout << dis->data;
            dis = dis->next;
        }
    }
    
    //释放动态申请的空间
    void distroy(node *nn)
    {
        if (nn==NULL)
        {
            return ;
        }
        while (nn!=NULL)
        {
            node *tmp = nn;
            nn = nn->next;
            delete tmp;
        }
    }
    
    
    void test_by_referenceToPointer()
    {
        node *test = NULL;
        char *test_array="wang_shi_hui";
        init_node_by_referenceToPointer(test,test_array);
        //如果输入参数是指向指针的引用
        display(test,"单链表逆置前
    ");
        cout << "
     init_node_by_referenceToPointer" << endl;
        node *tmp = node_reverse(test);
        if(test==NULL)
            exit(0);
        display(tmp,"单链表逆置后
    ");
        //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
        //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
        distroy(tmp);//释放动态申请的内存
        tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
        test = NULL;
        cout << "
     after destory tmp= " << tmp << endl;
    
        //如果上面没有tmp = NULL;test = NULL;,display将会出错,
        //因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,
        //那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,
        //这样就会出现异常.
        display(test);
    
    }
    void test_by_pointerToPointer()
    {
        node *test = NULL;
        char *test_array="123456789";
        init_node_by_pointerToPointer(&test,test_array);
        //如果输入参数是指向指针的指针
        display(test,"单链表逆置前
    ");
        cout << "
     init_node_by_pointerToPointer" << endl;
        node *tmp = node_reverse(test);
        if(test==NULL)
            exit(0);
        display(tmp,"单链表逆置后
    ");
        //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
        //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
        distroy(tmp);//释放动态申请的内存
        tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
        test = NULL;
        cout << "
     after destory tmp= " << tmp << endl;
    
        //如果上面没有tmp = NULL;test = NULL;,display将会出错,
        //因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,
        //那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,
        //这样就会出现异常.
        display(test);
    
    }
    int main()
    {
        test_by_referenceToPointer();
        cout<<"
    ---------------------
    ";
        test_by_pointerToPointer();
    }
    /************************************************
    单链表逆置前
    iuh_ihs_gnaw
     init_node_by_referenceToPointer
    单链表逆置后
    wang_shi_hui
     after destory tmp= 0
    no data to display
    
    ---------------------
    单链表逆置前
    987654321
     init_node_by_pointerToPointer
    单链表逆置后
    123456789
     after destory tmp= 0
    no data to display
    *************************************************/
    



  • 相关阅读:
    关于asp.net页面自定义404错误码返回302的最新解决方法
    基于sharpdevelop核心和ArcEngine打造插件式桌面GIS应用(概述)
    WPF自定义控件踩坑记录,用户自定义控件 绑定后台定义的 命令 依赖项属性 注意事项 静态
    WPF C# 以非独占式读取本地图片
    C#DataGridView控件60招(一)
    用TEXT文件做数据源
    boost智能指针
    linux下安装boost库
    ASP/ASP.NET程序设计电子书专题下载
    Highcharts 点击多选框取消,添加数据上绑定最大,最小值和图例上绑定提示框数据
  • 原文地址:https://www.cnblogs.com/dyllove98/p/3223597.html
Copyright © 2020-2023  润新知