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


#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\n";
        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,"单链表逆置前\n");
    cout << "\n init_node_by_referenceToPointer" << endl;
    node *tmp = node_reverse(test);
    if(test==NULL)
        exit(0);
    display(tmp,"单链表逆置后\n");
    //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
    //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
    distroy(tmp);//释放动态申请的内存
    tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
    test = NULL;
    cout << "\n 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,"单链表逆置前\n");
    cout << "\n init_node_by_pointerToPointer" << endl;
    node *tmp = node_reverse(test);
    if(test==NULL)
        exit(0);
    display(tmp,"单链表逆置后\n");
    //tmp和test指向的存储空间已经使用完毕,应该释放掉他们申请的空间!
    //并且,要将他们赋值为NULL,否则他们将成为野指针!!!!,一定要注意了~~
    distroy(tmp);//释放动态申请的内存
    tmp = NULL;//将他们重新赋值为NULL,不然就会成为野指针~~~~~
    test = NULL;
    cout << "\n after destory tmp= " << tmp << endl;

    //如果上面没有tmp = NULL;test = NULL;,display将会出错,
    //因为在display开始的时候判断传入的参数是否为NULL,如果不把野指针赋值为NULL,
    //那么判断就没有效果,会继续指向display中的while语句,而此时指针所指向的存储空间已经被释放掉了,
    //这样就会出现异常.
    display(test);

}
int main()
{
    test_by_referenceToPointer();
    cout<<"\n---------------------\n";
    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
*************************************************/



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